| Index: src/IceCfgNode.cpp
|
| diff --git a/src/IceCfgNode.cpp b/src/IceCfgNode.cpp
|
| index 2bcea9ad255da9671ab0817fda8f678c86fbb3e0..f6c63797d87d761fe50f558facc168c5fa140953 100644
|
| --- a/src/IceCfgNode.cpp
|
| +++ b/src/IceCfgNode.cpp
|
| @@ -299,14 +299,29 @@ CfgNode *CfgNode::splitIncomingEdge(CfgNode *Pred, SizeT EdgeIndex) {
|
| namespace {
|
|
|
| // Helper function used by advancedPhiLowering().
|
| -bool sameVarOrReg(const Variable *Var, const Operand *Opnd) {
|
| - if (Var == Opnd)
|
| +bool sameVarOrReg(TargetLowering *Target, const Variable *Var1,
|
| + const Operand *Opnd) {
|
| + if (Var1 == Opnd)
|
| return true;
|
| - if (const auto Var2 = llvm::dyn_cast<Variable>(Opnd)) {
|
| - if (Var->hasReg() && Var->getRegNum() == Var2->getRegNum())
|
| - return true;
|
| - }
|
| - return false;
|
| + const auto Var2 = llvm::dyn_cast<Variable>(Opnd);
|
| + if (Var2 == nullptr)
|
| + return false;
|
| +
|
| + // If either operand lacks a register, they cannot be the same.
|
| + if (!Var1->hasReg())
|
| + return false;
|
| + if (!Var2->hasReg())
|
| + return false;
|
| +
|
| + int32_t RegNum1 = Var1->getRegNum();
|
| + int32_t RegNum2 = Var2->getRegNum();
|
| + // Quick common-case check.
|
| + if (RegNum1 == RegNum2)
|
| + return true;
|
| +
|
| + assert(Target->getAliasesForRegister(RegNum1)[RegNum2] ==
|
| + Target->getAliasesForRegister(RegNum2)[RegNum1]);
|
| + return Target->getAliasesForRegister(RegNum1)[RegNum2];
|
| }
|
|
|
| } // end of anonymous namespace
|
| @@ -383,6 +398,7 @@ void CfgNode::advancedPhiLowering() {
|
| if (NumPhis == 0)
|
| return;
|
|
|
| + TargetLowering *Target = Func->getTarget();
|
| SizeT InEdgeIndex = 0;
|
| for (CfgNode *Pred : InEdges) {
|
| CfgNode *Split = splitIncomingEdge(Pred, InEdgeIndex++);
|
| @@ -397,7 +413,7 @@ void CfgNode::advancedPhiLowering() {
|
| Desc[I].NumPred = 0;
|
| // Cherry-pick any trivial assignments, so that they don't contribute to
|
| // the running complexity of the topological sort.
|
| - if (sameVarOrReg(Dest, Src)) {
|
| + if (sameVarOrReg(Target, Dest, Src)) {
|
| Desc[I].Processed = true;
|
| --Remaining;
|
| if (Dest != Src)
|
| @@ -420,10 +436,10 @@ void CfgNode::advancedPhiLowering() {
|
| if (I != J) {
|
| // There shouldn't be two Phis with the same Dest variable or
|
| // register.
|
| - assert(!sameVarOrReg(Dest, Desc[J].Dest));
|
| + assert(!sameVarOrReg(Target, Dest, Desc[J].Dest));
|
| }
|
| const Operand *Src = Desc[J].Src;
|
| - if (sameVarOrReg(Dest, Src))
|
| + if (sameVarOrReg(Target, Dest, Src))
|
| ++Desc[I].NumPred;
|
| }
|
| }
|
| @@ -473,7 +489,7 @@ void CfgNode::advancedPhiLowering() {
|
| assert(Desc[BestIndex].NumPred <= 1);
|
| Variable *Dest = Desc[BestIndex].Dest;
|
| Operand *Src = Desc[BestIndex].Src;
|
| - assert(!sameVarOrReg(Dest, Src));
|
| + assert(!sameVarOrReg(Target, Dest, Src));
|
| // Break a cycle by introducing a temporary.
|
| if (Desc[BestIndex].NumPred) {
|
| bool Found = false;
|
| @@ -484,7 +500,7 @@ void CfgNode::advancedPhiLowering() {
|
| if (Desc[J].Processed)
|
| continue;
|
| Operand *OtherSrc = Desc[J].Src;
|
| - if (Desc[J].NumPred && sameVarOrReg(Dest, OtherSrc)) {
|
| + if (Desc[J].NumPred && sameVarOrReg(Target, Dest, OtherSrc)) {
|
| SizeT VarNum = Func->getNumVariables();
|
| Variable *Tmp = Func->makeVariable(OtherSrc->getType());
|
| if (BuildDefs::dump())
|
| @@ -505,7 +521,7 @@ void CfgNode::advancedPhiLowering() {
|
| for (size_t I = 0; I < NumPhis; ++I) {
|
| if (Desc[I].Processed)
|
| continue;
|
| - if (sameVarOrReg(Var, Desc[I].Dest)) {
|
| + if (sameVarOrReg(Target, Var, Desc[I].Dest)) {
|
| if (--Desc[I].NumPred == 0)
|
| Desc[I].Weight += WeightNoPreds;
|
| }
|
| @@ -1030,8 +1046,11 @@ void CfgNode::emit(Cfg *Func) const {
|
| // 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)))
|
| + if (DecorateAsm && Dest->hasReg()) {
|
| ++LiveRegCount[Dest->getRegNum()];
|
| + if (I.isLastUse(I.getSrc(0)))
|
| + --LiveRegCount[llvm::cast<Variable>(I.getSrc(0))->getRegNum()];
|
| + }
|
| continue;
|
| }
|
| I.emit(Func);
|
|
|