summaryrefslogtreecommitdiff
path: root/backend
diff options
context:
space:
mode:
authorRuiling Song <ruiling.song@intel.com>2014-06-03 13:53:14 +0800
committerZhigang Gong <zhigang.gong@intel.com>2014-06-04 10:15:02 +0800
commit38adc9b13bcaacdb0d3e916d9a46cea2ec708b0e (patch)
tree31fc2fe4b6a4b3f353621baa6b1294358ed869da /backend
parent7909661befc1b4064ca8c22bb1471bb6a7d9e39c (diff)
Revert "GBE: No need to compute liveout again in value.cpp."
We need to transfer ValueDef from predecessors to their successors. Consider a register defined in BB0, and used in BB3. we need to iterate over liveout to pass the def in BB0 to BB3, so the use in BB3 could get that correct def. Otherwise, the UD/DU graph is incomplete. This reverts commit 89b490b5a17cfda2d9816dc1c246ce5bbff12648. Reviewed-by: Zhigang Gong <zhigang.gong@linux.intel.com>
Diffstat (limited to 'backend')
-rw-r--r--backend/src/ir/value.cpp33
1 files changed, 33 insertions, 0 deletions
diff --git a/backend/src/ir/value.cpp b/backend/src/ir/value.cpp
index cdc1a4c6..1dbd4f4d 100644
--- a/backend/src/ir/value.cpp
+++ b/backend/src/ir/value.cpp
@@ -66,6 +66,8 @@ namespace ir {
* registers
*/
void initializeOtherDef(void);
+ /*! Iterate to completely transfer the liveness and get the def sets */
+ void iterateLiveOut(void);
/*! Use custom allocators */
GBE_CLASS(LiveOutSet);
};
@@ -78,6 +80,7 @@ namespace ir {
{
this->initializeInstructionDef();
this->initializeOtherDef();
+ this->iterateLiveOut();
}
LiveOutSet::RegDefSet &LiveOutSet::getDefSet(const BasicBlock *bb, Register reg)
@@ -224,6 +227,36 @@ namespace ir {
}
}
+ void LiveOutSet::iterateLiveOut(void) {
+ bool changed = true;
+
+ while (changed) {
+ changed = false;
+
+ // Compute the union of the current liveout definitions with the previous
+ // ones. Do not take into account the killed values though
+ liveness.foreach<DF_PRED>([&](Liveness::BlockInfo &curr,
+ const Liveness::BlockInfo &pred)
+ {
+ const BasicBlock &bb = curr.bb;
+ const BasicBlock &pbb = pred.bb;
+ for (auto reg : curr.liveOut) {
+ if (pred.inLiveOut(reg) == false) continue;
+ if (curr.inVarKill(reg) == true) continue;
+ RegDefSet &currSet = this->getDefSet(&bb, reg);
+ RegDefSet &predSet = this->getDefSet(&pbb, reg);
+
+ // Transfer the values
+ for (auto def : predSet) {
+ if (currSet.contains(def)) continue;
+ changed = true;
+ currSet.insert(def);
+ }
+ }
+ });
+ }
+ }
+
LiveOutSet::~LiveOutSet(void) {
for (const auto pair : defMap) {
BlockDefMap *block = pair.second;