diff options
author | Ruiling Song <ruiling.song@intel.com> | 2014-06-03 13:53:14 +0800 |
---|---|---|
committer | Zhigang Gong <zhigang.gong@intel.com> | 2014-06-04 10:15:02 +0800 |
commit | 38adc9b13bcaacdb0d3e916d9a46cea2ec708b0e (patch) | |
tree | 31fc2fe4b6a4b3f353621baa6b1294358ed869da /backend | |
parent | 7909661befc1b4064ca8c22bb1471bb6a7d9e39c (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.cpp | 33 |
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; |