| Index: src/IceRegAlloc.cpp
|
| diff --git a/src/IceRegAlloc.cpp b/src/IceRegAlloc.cpp
|
| index ea15b1b6db8cbb5280030bd25fb1554ec785e8ba..26b350a5e40ef9b83932110675b092b1ec357922 100644
|
| --- a/src/IceRegAlloc.cpp
|
| +++ b/src/IceRegAlloc.cpp
|
| @@ -493,20 +493,18 @@ 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]) {
|
| + FOREACH_VAR_IN_INST(SrcVar, *DefInst) {
|
| + // 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()) {
|
| + const int32_t SrcReg = SrcVar->getRegNumTmp();
|
| + const bool IsAliasAvailable =
|
| + (Iter.RegMask & *RegAliases[SrcReg]).any();
|
| + if (IsAliasAvailable) {
|
| if (FindOverlap && !Iter.Free[SrcReg]) {
|
| // Don't bother trying to enable AllowOverlap if the register is
|
| // already free.
|
| @@ -516,6 +514,14 @@ void LinearScan::findRegisterPreference(IterationState &Iter) {
|
| 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.
|
| + FOREACH_VAR_IN_INST_BREAK;
|
| }
|
| }
|
| }
|
| @@ -539,6 +545,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.
|
| 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 +859,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.
|
| if (Item != Iter.Prefer && RegNum == Iter.PreferReg &&
|
| overlapsDefs(Func, Iter.Cur, Item)) {
|
| Iter.AllowOverlap = false;
|
|
|