Index: src/IceRegAlloc.cpp |
diff --git a/src/IceRegAlloc.cpp b/src/IceRegAlloc.cpp |
index ea15b1b6db8cbb5280030bd25fb1554ec785e8ba..712dbced5d810dca626eaf87fe75fd58ddbc028a 100644 |
--- a/src/IceRegAlloc.cpp |
+++ b/src/IceRegAlloc.cpp |
@@ -493,30 +493,32 @@ void LinearScan::findRegisterPreference(IterationState &Iter) { |
if (const Inst *DefInst = |
VMetadata->getFirstDefinitionSingleBlock(Iter.Cur)) { |
assert(DefInst->getDest() == Iter.Cur); |
- bool IsAssign = DefInst->isSimpleAssign(); |
+ bool IsAssign = DefInst->isVarAssign(); |
bool IsSingleDef = !VMetadata->isMultiDef(Iter.Cur); |
- for (SizeT i = 0; i < DefInst->getSrcSize(); ++i) { |
- // TODO(stichnot): Iterate through the actual Variables of the |
- // instruction, not just the source operands. This could capture Load |
- // instructions, including address mode optimization, for Prefer (but |
- // not for AllowOverlap). |
- if (Variable *SrcVar = llvm::dyn_cast<Variable>(DefInst->getSrc(i))) { |
- int32_t SrcReg = SrcVar->getRegNumTmp(); |
- // Only consider source variables that have (so far) been assigned a |
- // register. That register must be one in the RegMask set, e.g. don't |
- // try to prefer the stack pointer as a result of the stacksave |
- // intrinsic. |
- if (SrcVar->hasRegTmp() && Iter.RegMask[SrcReg]) { |
- if (FindOverlap && !Iter.Free[SrcReg]) { |
- // Don't bother trying to enable AllowOverlap if the register is |
- // already free. |
- Iter.AllowOverlap = IsSingleDef && IsAssign && |
- !overlapsDefs(Func, Iter.Cur, SrcVar); |
- } |
- if (Iter.AllowOverlap || Iter.Free[SrcReg]) { |
- Iter.Prefer = SrcVar; |
- Iter.PreferReg = SrcReg; |
- } |
+ FOREACH_VAR_IN_INST(SrcVar, *DefInst) { |
+ int32_t SrcReg = SrcVar->getRegNumTmp(); |
+ // Only consider source variables that have (so far) been assigned a |
+ // register. That register must be one in the RegMask set, e.g. don't |
+ // try to prefer the stack pointer as a result of the stacksave |
+ // intrinsic. |
+ if (SrcVar->hasRegTmp() && (Iter.RegMask & *RegAliases[SrcReg]).any()) { |
John
2015/10/12 15:35:17
this is super hard to read!!!
const bool SrcVarRe
Jim Stichnoth
2015/10/12 17:27:31
Done. Note that I want to put the cheap hasRegTmp
John
2015/10/12 20:39:58
Then you can define a static method (in an unnamed
|
+ if (FindOverlap && !Iter.Free[SrcReg]) { |
+ // Don't bother trying to enable AllowOverlap if the register is |
+ // already free. |
+ Iter.AllowOverlap = IsSingleDef && IsAssign && |
+ !overlapsDefs(Func, Iter.Cur, SrcVar); |
+ } |
+ if (Iter.AllowOverlap || Iter.Free[SrcReg]) { |
+ Iter.Prefer = SrcVar; |
+ Iter.PreferReg = SrcReg; |
+ // Stop looking for a preference after the first valid preference is |
+ // found. One might think that we should look at all instruction |
+ // variables to find the best <Prefer,AllowOverlap> combination, but |
+ // note that AllowOverlap can only be true for a simple assignment |
+ // statement which can have only one source operand, so it's not |
+ // possible for AllowOverlap to be true beyond the first source |
+ // operand. |
+ break; |
} |
} |
} |
@@ -539,6 +541,7 @@ void LinearScan::filterFreeWithInactiveRanges(IterationState &Iter) { |
if (!Item->rangeOverlaps(Iter.Cur)) |
continue; |
const llvm::SmallBitVector &Aliases = *RegAliases[Item->getRegNumTmp()]; |
+ // TODO(stichnot): Do this with bitvector ops, not a loop, for efficiency. |
John
2015/10/12 15:35:17
this is a simple TODOne:
for (int32_t RegAlias =
Jim Stichnoth
2015/10/12 17:27:31
What I mean is, I think it can be changed to somet
|
for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
RegAlias = Aliases.find_next(RegAlias)) { |
// Don't assert(Free[RegNum]) because in theory (though probably never in |
@@ -852,6 +855,8 @@ void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull, |
if (Iter.AllowOverlap) { |
for (const Variable *Item : Active) { |
int32_t RegNum = Item->getRegNumTmp(); |
+ // TODO(stichnot): Consider aliases of RegNum. This is probably a |
+ // correctness issue. |
John
2015/10/12 15:35:17
This is definitively a correctness issue... :(
Jim Stichnoth
2015/10/12 17:27:31
Yeah, I want to address it in the context of the x
|
if (Item != Iter.Prefer && RegNum == Iter.PreferReg && |
overlapsDefs(Func, Iter.Cur, Item)) { |
Iter.AllowOverlap = false; |