summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Hexagon/HexagonSubtarget.cpp
diff options
context:
space:
mode:
authorKrzysztof Parzyszek <kparzysz@codeaurora.org>2017-08-28 18:36:21 +0000
committerKrzysztof Parzyszek <kparzysz@codeaurora.org>2017-08-28 18:36:21 +0000
commit2164a271a333d4e822c95b977002d68f81c8c636 (patch)
treeac8b28fdce40c1880c91b16ed491af72c64998ec /llvm/lib/Target/Hexagon/HexagonSubtarget.cpp
parent312c557b3b1d989faaf4437107cb8487bca6d515 (diff)
downloadbcm5719-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/HexagonSubtarget.cpp')
-rw-r--r--llvm/lib/Target/Hexagon/HexagonSubtarget.cpp51
1 files changed, 51 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(
OpenPOWER on IntegriCloud