Index: src/IceCfgNode.cpp |
diff --git a/src/IceCfgNode.cpp b/src/IceCfgNode.cpp |
index 19c5d22d731879dff9ab258632028102dc234317..529e557e249a129cc234a89ddadabb2325b5f863 100644 |
--- a/src/IceCfgNode.cpp |
+++ b/src/IceCfgNode.cpp |
@@ -885,6 +885,10 @@ void CfgNode::emit(Cfg *Func) const { |
bool DecorateAsm = |
Liveness && Func->getContext()->getFlags().getDecorateAsm(); |
Str << getAsmName() << ":\n"; |
+ // LiveRegCount keeps track of the number of currently live |
+ // variables that each register is assigned to. Normally that would |
+ // be only 0 or 1, but the register allocator's AllowOverlap |
+ // inference allows it to be greater than 1 for short periods. |
std::vector<SizeT> LiveRegCount(Func->getTarget()->getNumRegisters()); |
if (DecorateAsm) { |
const bool IsLiveIn = true; |
@@ -900,8 +904,21 @@ void CfgNode::emit(Cfg *Func) const { |
for (const Inst &I : Insts) { |
if (I.isDeleted()) |
continue; |
- if (I.isRedundantAssign()) |
+ if (I.isRedundantAssign()) { |
+ // Usually, redundant assignments end the live range of the src |
+ // variable and begin the live range of the dest variable, with |
+ // no net effect on the liveness of their register. However, if |
+ // the register allocator infers the AllowOverlap condition, |
+ // then this may be a redundant assignment that does not end the |
+ // src variable's live range, in which case the active variable |
+ // count for that register needs to be bumped. That normally |
+ // would have happened as part of emitLiveRangesEnded(), but |
+ // that isn't called for redundant assignments. |
+ Variable *Dest = I.getDest(); |
+ if (DecorateAsm && Dest->hasReg() && !I.isLastUse(I.getSrc(0))) |
jvoung (off chromium)
2015/05/27 15:58:56
Just checking -- this checks !I.isLastUse(I.getSrc
Jim Stichnoth
2015/05/27 16:08:55
Sorry - I discovered that problem yesterday and up
|
+ ++LiveRegCount[Dest->getRegNum()]; |
continue; |
+ } |
I.emit(Func); |
if (DecorateAsm) |
emitLiveRangesEnded(Str, Func, &I, LiveRegCount); |