diff options
| author | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2017-08-28 18:36:21 +0000 |
|---|---|---|
| committer | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2017-08-28 18:36:21 +0000 |
| commit | 2164a271a333d4e822c95b977002d68f81c8c636 (patch) | |
| tree | ac8b28fdce40c1880c91b16ed491af72c64998ec /llvm/lib/Target/Hexagon | |
| parent | 312c557b3b1d989faaf4437107cb8487bca6d515 (diff) | |
| download | bcm5719-llvm-2164a271a333d4e822c95b977002d68f81c8c636.tar.gz bcm5719-llvm-2164a271a333d4e822c95b977002d68f81c8c636.zip | |
[Hexagon] Check for potential bank conflicts in post-RA scheduling
Insert artificial edges between loads that could cause a cache bank
conflict.
llvm-svn: 311901
Diffstat (limited to 'llvm/lib/Target/Hexagon')
| -rw-r--r-- | llvm/lib/Target/Hexagon/HexagonSubtarget.cpp | 51 | ||||
| -rw-r--r-- | llvm/lib/Target/Hexagon/HexagonSubtarget.h | 3 | ||||
| -rw-r--r-- | llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp | 1 |
3 files changed, 55 insertions, 0 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonSubtarget.cpp b/llvm/lib/Target/Hexagon/HexagonSubtarget.cpp index d9fa3b2548e..5803886f8b0 100644 --- a/llvm/lib/Target/Hexagon/HexagonSubtarget.cpp +++ b/llvm/lib/Target/Hexagon/HexagonSubtarget.cpp @@ -93,6 +93,10 @@ static cl::opt<bool> SchedPredsCloser("sched-preds-closer", static cl::opt<bool> SchedRetvalOptimization("sched-retval-optimization", cl::Hidden, cl::ZeroOrMore, cl::init(true)); +static cl::opt<bool> EnableCheckBankConflict("hexagon-check-bank-conflict", + cl::Hidden, cl::ZeroOrMore, cl::init(true), + cl::desc("Enable checking for cache bank conflicts")); + void HexagonSubtarget::initializeEnvironment() { UseMemOps = false; @@ -247,6 +251,52 @@ void HexagonSubtarget::CallMutation::apply(ScheduleDAGInstrs *DAG) { } } +void HexagonSubtarget::BankConflictMutation::apply(ScheduleDAGInstrs *DAG) { + if (!EnableCheckBankConflict) + return; + + const auto &HII = static_cast<const HexagonInstrInfo&>(*DAG->TII); + + // Create artificial edges between loads that could likely cause a bank + // conflict. Since such loads would normally not have any dependency + // between them, we cannot rely on existing edges. + for (unsigned i = 0, e = DAG->SUnits.size(); i != e; ++i) { + SUnit &S0 = DAG->SUnits[i]; + MachineInstr &L0 = *S0.getInstr(); + if (!L0.mayLoad() || L0.mayStore() || + HII.getAddrMode(L0) != HexagonII::BaseImmOffset) + continue; + int Offset0; + unsigned Size0; + unsigned Base0 = HII.getBaseAndOffset(L0, Offset0, Size0); + // Is the access size is longer than the L1 cache line, skip the check. + if (Base0 == 0 || Size0 >= 32) + continue; + // Scan only up to 32 instructions ahead (to avoid n^2 complexity). + for (unsigned j = i+1, m = std::min(i+32, e); j != m; ++j) { + SUnit &S1 = DAG->SUnits[j]; + MachineInstr &L1 = *S1.getInstr(); + if (!L1.mayLoad() || L1.mayStore() || + HII.getAddrMode(L1) != HexagonII::BaseImmOffset) + continue; + int Offset1; + unsigned Size1; + unsigned Base1 = HII.getBaseAndOffset(L1, Offset1, Size1); + if (Base1 == 0 || Size1 >= 32 || Base0 != Base1) + continue; + // Check bits 3 and 4 of the offset: if they differ, a bank conflict + // is unlikely. + if (((Offset0 ^ Offset1) & 0x18) != 0) + continue; + // Bits 3 and 4 are the same, add an artificial edge and set extra + // latency. + SDep A(&S0, SDep::Artificial); + A.setLatency(1); + S1.addPred(A, true); + } + } +} + HexagonSubtarget::HexagonSubtarget(const Triple &TT, StringRef CPU, StringRef FS, const TargetMachine &TM) @@ -330,6 +380,7 @@ void HexagonSubtarget::getPostRAMutations( std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) const { Mutations.push_back(llvm::make_unique<UsrOverflowMutation>()); Mutations.push_back(llvm::make_unique<HVXMemLatencyMutation>()); + Mutations.push_back(llvm::make_unique<BankConflictMutation>()); } void HexagonSubtarget::getSMSMutations( diff --git a/llvm/lib/Target/Hexagon/HexagonSubtarget.h b/llvm/lib/Target/Hexagon/HexagonSubtarget.h index 542929d94a7..bdaf12e17d9 100644 --- a/llvm/lib/Target/Hexagon/HexagonSubtarget.h +++ b/llvm/lib/Target/Hexagon/HexagonSubtarget.h @@ -68,6 +68,9 @@ public: bool shouldTFRICallBind(const HexagonInstrInfo &HII, const SUnit &Inst1, const SUnit &Inst2) const; }; + struct BankConflictMutation : public ScheduleDAGMutation { + void apply(ScheduleDAGInstrs *DAG) override; + }; private: std::string CPUString; diff --git a/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp b/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp index a6d134365a6..9b4530f2297 100644 --- a/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp +++ b/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp @@ -105,6 +105,7 @@ HexagonPacketizerList::HexagonPacketizerList(MachineFunction &MF, addMutation(make_unique<HexagonSubtarget::UsrOverflowMutation>()); addMutation(make_unique<HexagonSubtarget::HVXMemLatencyMutation>()); + addMutation(make_unique<HexagonSubtarget::BankConflictMutation>()); } // Check if FirstI modifies a register that SecondI reads. |

