| Index: src/IceTargetLoweringX8632.cpp
|
| diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp
|
| index ab021c6ef6fd9b143df869802c02141340ed89f1..dfb1fdad838bbb69b04783ac87273b3612ff8589 100644
|
| --- a/src/IceTargetLoweringX8632.cpp
|
| +++ b/src/IceTargetLoweringX8632.cpp
|
| @@ -453,8 +453,10 @@ Variable *TargetX8632::getPhysicalRegister(SizeT RegNum) {
|
| PhysicalRegisters[RegNum] = Reg;
|
| // Specially mark esp as an "argument" so that it is considered
|
| // live upon function entry.
|
| - if (RegNum == RegX8632::Reg_esp)
|
| + if (RegNum == RegX8632::Reg_esp) {
|
| Func->addImplicitArg(Reg);
|
| + Reg->setIgnoreLiveness();
|
| + }
|
| }
|
| return Reg;
|
| }
|
| @@ -1257,12 +1259,11 @@ void TargetX8632::lowerArithmetic(const InstArithmetic *Inst) {
|
| _shl(T_2, T_1);
|
| _test(T_1, BitTest);
|
| _br(CondX86::Br_e, Label);
|
| - // Because of the intra-block control flow, we need to fake a use
|
| - // of T_3 to prevent its earlier definition from being dead-code
|
| - // eliminated in the presence of its later definition.
|
| - Context.insert(InstFakeUse::create(Func, T_3));
|
| - _mov(T_3, T_2);
|
| - _mov(T_2, Zero);
|
| + // T_2 and T_3 are being assigned again because of the
|
| + // intra-block control flow, so we need the _mov_nonkillable
|
| + // variant to avoid liveness problems.
|
| + _mov_nonkillable(T_3, T_2);
|
| + _mov_nonkillable(T_2, Zero);
|
| Context.insert(Label);
|
| _mov(DestLo, T_2);
|
| _mov(DestHi, T_3);
|
| @@ -1293,12 +1294,11 @@ void TargetX8632::lowerArithmetic(const InstArithmetic *Inst) {
|
| _shr(T_3, T_1);
|
| _test(T_1, BitTest);
|
| _br(CondX86::Br_e, Label);
|
| - // Because of the intra-block control flow, we need to fake a use
|
| - // of T_3 to prevent its earlier definition from being dead-code
|
| - // eliminated in the presence of its later definition.
|
| - Context.insert(InstFakeUse::create(Func, T_2));
|
| - _mov(T_2, T_3);
|
| - _mov(T_3, Zero);
|
| + // T_2 and T_3 are being assigned again because of the
|
| + // intra-block control flow, so we need the _mov_nonkillable
|
| + // variant to avoid liveness problems.
|
| + _mov_nonkillable(T_2, T_3);
|
| + _mov_nonkillable(T_3, Zero);
|
| Context.insert(Label);
|
| _mov(DestLo, T_2);
|
| _mov(DestHi, T_3);
|
| @@ -1329,11 +1329,11 @@ void TargetX8632::lowerArithmetic(const InstArithmetic *Inst) {
|
| _sar(T_3, T_1);
|
| _test(T_1, BitTest);
|
| _br(CondX86::Br_e, Label);
|
| - // Because of the intra-block control flow, we need to fake a use
|
| - // of T_3 to prevent its earlier definition from being dead-code
|
| - // eliminated in the presence of its later definition.
|
| - Context.insert(InstFakeUse::create(Func, T_2));
|
| - _mov(T_2, T_3);
|
| + // T_2 and T_3 are being assigned again because of the
|
| + // intra-block control flow, so T_2 needs the _mov_nonkillable
|
| + // variant to avoid liveness problems. T_3 doesn't need special
|
| + // treatment because it is reassigned via _sar instead of _mov.
|
| + _mov_nonkillable(T_2, T_3);
|
| _sar(T_3, SignExtend);
|
| Context.insert(Label);
|
| _mov(DestLo, T_2);
|
| @@ -2516,10 +2516,9 @@ void TargetX8632::lowerFcmp(const InstFcmp *Inst) {
|
| if (HasC2) {
|
| _br(TableFcmp[Index].C2, Label);
|
| }
|
| - Context.insert(InstFakeUse::create(Func, Dest));
|
| Constant *NonDefault =
|
| Ctx->getConstantInt32(IceType_i32, !TableFcmp[Index].Default);
|
| - _mov(Dest, NonDefault);
|
| + _mov_nonkillable(Dest, NonDefault);
|
| Context.insert(Label);
|
| }
|
| }
|
| @@ -2675,8 +2674,7 @@ void TargetX8632::lowerIcmp(const InstIcmp *Inst) {
|
| _br(CondX86::Br_ne, Label);
|
| _cmp(Src0HiRM, Src1HiRI);
|
| _br(CondX86::Br_ne, Label);
|
| - Context.insert(InstFakeUse::create(Func, Dest));
|
| - _mov(Dest, (Condition == InstIcmp::Eq ? One : Zero));
|
| + _mov_nonkillable(Dest, (Condition == InstIcmp::Eq ? One : Zero));
|
| Context.insert(Label);
|
| } else {
|
| InstX8632Label *LabelFalse = InstX8632Label::create(Func, this);
|
| @@ -2688,8 +2686,7 @@ void TargetX8632::lowerIcmp(const InstIcmp *Inst) {
|
| _cmp(Src0LoRM, Src1LoRI);
|
| _br(TableIcmp64[Index].C3, LabelTrue);
|
| Context.insert(LabelFalse);
|
| - Context.insert(InstFakeUse::create(Func, Dest));
|
| - _mov(Dest, Zero);
|
| + _mov_nonkillable(Dest, Zero);
|
| Context.insert(LabelTrue);
|
| }
|
| return;
|
| @@ -2702,8 +2699,7 @@ void TargetX8632::lowerIcmp(const InstIcmp *Inst) {
|
| _cmp(Src0RM, Src1);
|
| _mov(Dest, One);
|
| _br(getIcmp32Mapping(Inst->getCondition()), Label);
|
| - Context.insert(InstFakeUse::create(Func, Dest));
|
| - _mov(Dest, Zero);
|
| + _mov_nonkillable(Dest, Zero);
|
| Context.insert(Label);
|
| }
|
|
|
| @@ -3134,7 +3130,7 @@ void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
|
| }
|
| case Intrinsics::Stackrestore: {
|
| Variable *esp = Func->getTarget()->getPhysicalRegister(RegX8632::Reg_esp);
|
| - _mov(esp, Instr->getArg(0));
|
| + _mov_nonkillable(esp, Instr->getArg(0));
|
| return;
|
| }
|
| case Intrinsics::Trap:
|
| @@ -3943,22 +3939,19 @@ void TargetX8632::lowerSelect(const InstSelect *Inst) {
|
| _mov(DestLo, SrcLoRI);
|
| _mov(DestHi, SrcHiRI);
|
| _br(CondX86::Br_ne, Label);
|
| - Context.insert(InstFakeUse::create(Func, DestLo));
|
| - Context.insert(InstFakeUse::create(Func, DestHi));
|
| Operand *SrcFLo = loOperand(SrcF);
|
| Operand *SrcFHi = hiOperand(SrcF);
|
| SrcLoRI = legalize(SrcFLo, Legal_Reg | Legal_Imm);
|
| SrcHiRI = legalize(SrcFHi, Legal_Reg | Legal_Imm);
|
| - _mov(DestLo, SrcLoRI);
|
| - _mov(DestHi, SrcHiRI);
|
| + _mov_nonkillable(DestLo, SrcLoRI);
|
| + _mov_nonkillable(DestHi, SrcHiRI);
|
| } else {
|
| _cmp(ConditionRM, Zero);
|
| SrcT = legalize(SrcT, Legal_Reg | Legal_Imm);
|
| _mov(Dest, SrcT);
|
| _br(CondX86::Br_ne, Label);
|
| - Context.insert(InstFakeUse::create(Func, Dest));
|
| SrcF = legalize(SrcF, Legal_Reg | Legal_Imm);
|
| - _mov(Dest, SrcF);
|
| + _mov_nonkillable(Dest, SrcF);
|
| }
|
|
|
| Context.insert(Label);
|
| @@ -4299,9 +4292,22 @@ Variable *TargetX8632::makeReg(Type Type, int32_t RegNum) {
|
| }
|
|
|
| void TargetX8632::postLower() {
|
| - if (Ctx->getOptLevel() != Opt_m1)
|
| + if (Ctx->getOptLevel() != Opt_m1) {
|
| + // Find two-address non-SSA instructions where Dest==Src0, and set
|
| + // the DestNonKillable flag to keep liveness analysis consistent.
|
| + for (Inst *Inst : Context) {
|
| + if (Inst->isDeleted())
|
| + continue;
|
| + if (Variable *Dest = Inst->getDest()) {
|
| + // TODO(stichnot): We may need to consider all source
|
| + // operands, not just the first one, if using 3-address
|
| + // instructions.
|
| + if (Inst->getSrcSize() > 0 && Inst->getSrc(0) == Dest)
|
| + Inst->setDestNonKillable();
|
| + }
|
| + }
|
| return;
|
| - TimerMarker T(TimerStack::TT_postLower, Func);
|
| + }
|
| // TODO: Avoid recomputing WhiteList every instruction.
|
| RegSetMask RegInclude = RegSet_All;
|
| RegSetMask RegExclude = RegSet_StackPointer;
|
|
|