Chromium Code Reviews| Index: src/IceTargetLoweringX8632.cpp |
| diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp |
| index 7edb2c36f92fb2e7b5c1c62811f2feca6829daa2..e431861fcf98fc3552b1e4283384afaadf099877 100644 |
| --- a/src/IceTargetLoweringX8632.cpp |
| +++ b/src/IceTargetLoweringX8632.cpp |
| @@ -883,7 +883,7 @@ void TargetX8632::addProlog(CfgNode *Node) { |
| // that stack slot. |
| if (SpillVariable *SpillVar = llvm::dyn_cast<SpillVariable>(Var)) { |
| assert(Var->getWeight().isZero()); |
| - if (!SpillVar->getLinkedTo()->hasReg()) { |
| + if (SpillVar->getLinkedTo() && !SpillVar->getLinkedTo()->hasReg()) { |
| VariablesLinkedToSpillSlots.push_back(Var); |
| continue; |
| } |
| @@ -1160,8 +1160,9 @@ void TargetX8632::split64(Variable *Var) { |
| } |
| Operand *TargetX8632::loOperand(Operand *Operand) { |
| - assert(Operand->getType() == IceType_i64); |
| - if (Operand->getType() != IceType_i64) |
| + assert(Operand->getType() == IceType_i64 || |
| + Operand->getType() == IceType_f64); |
| + if (Operand->getType() != IceType_i64 && Operand->getType() != IceType_f64) |
| return Operand; |
| if (Variable *Var = llvm::dyn_cast<Variable>(Operand)) { |
| split64(Var); |
| @@ -1180,8 +1181,9 @@ Operand *TargetX8632::loOperand(Operand *Operand) { |
| } |
| Operand *TargetX8632::hiOperand(Operand *Operand) { |
| - assert(Operand->getType() == IceType_i64); |
| - if (Operand->getType() != IceType_i64) |
| + assert(Operand->getType() == IceType_i64 || |
| + Operand->getType() == IceType_f64); |
| + if (Operand->getType() != IceType_i64 && Operand->getType() != IceType_f64) |
| return Operand; |
| if (Variable *Var = llvm::dyn_cast<Variable>(Operand)) { |
| split64(Var); |
| @@ -2463,20 +2465,25 @@ void TargetX8632::lowerCast(const InstCast *Inst) { |
| // a_lo.i32 = t_lo.i32 |
| // t_hi.i32 = hi(s.f64) |
| // a_hi.i32 = t_hi.i32 |
| - SpillVariable *SpillVar = Func->makeVariable<SpillVariable>(IceType_f64); |
| - SpillVar->setLinkedTo(llvm::dyn_cast<Variable>(Src0RM)); |
| - Variable *Spill = SpillVar; |
| - Spill->setWeight(RegWeight::Zero); |
| - _movq(Spill, Src0RM); |
| + Operand *SpillLo, *SpillHi; |
| + if (auto *Src0Var = llvm::dyn_cast<Variable>(Src0RM)) { |
| + SpillVariable *SpillVar = |
| + Func->makeVariable<SpillVariable>(IceType_f64); |
| + SpillVar->setLinkedTo(Src0Var); |
| + Variable *Spill = SpillVar; |
| + Spill->setWeight(RegWeight::Zero); |
| + _movq(Spill, Src0RM); |
| + SpillLo = VariableSplit::create(Func, Spill, VariableSplit::Low); |
| + SpillHi = VariableSplit::create(Func, Spill, VariableSplit::High); |
| + } else { |
| + SpillLo = loOperand(Src0RM); |
| + SpillHi = hiOperand(Src0RM); |
| + } |
| Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
| Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
| Variable *T_Lo = makeReg(IceType_i32); |
| Variable *T_Hi = makeReg(IceType_i32); |
| - VariableSplit *SpillLo = |
| - VariableSplit::create(Func, Spill, VariableSplit::Low); |
| - VariableSplit *SpillHi = |
| - VariableSplit::create(Func, Spill, VariableSplit::High); |
| _mov(T_Lo, SpillLo); |
| _mov(DestLo, T_Lo); |
| @@ -2486,6 +2493,12 @@ void TargetX8632::lowerCast(const InstCast *Inst) { |
| case IceType_f64: { |
| Src0 = legalize(Src0); |
| assert(Src0->getType() == IceType_i64); |
| + if (llvm::isa<OperandX8632Mem>(Src0)) { |
| + Variable *T = Func->makeVariable(Dest->getType()); |
| + _movq(T, Src0); |
| + _movq(Dest, T); |
| + break; |
| + } |
| // a.f64 = bitcast b.i64 ==> |
| // t_lo.i32 = b_lo.i32 |
| // FakeDef(s.f64) |
| @@ -3955,14 +3968,14 @@ void computeAddressOpt(Cfg *Func, const Inst *Instr, Variable *&Base, |
| } // anonymous namespace |
| -void TargetX8632::lowerLoad(const InstLoad *Inst) { |
| +void TargetX8632::lowerLoad(const InstLoad *Load) { |
| // A Load instruction can be treated the same as an Assign |
| // instruction, after the source operand is transformed into an |
| // OperandX8632Mem operand. Note that the address mode |
| // optimization already creates an OperandX8632Mem operand, so it |
| // doesn't need another level of transformation. |
| - Type Ty = Inst->getDest()->getType(); |
| - Operand *Src0 = FormMemoryOperand(Inst->getSourceAddress(), Ty); |
| + Type Ty = Load->getDest()->getType(); |
| + Operand *Src0 = FormMemoryOperand(Load->getSourceAddress(), Ty); |
| // Fuse this load with a subsequent Arithmetic instruction in the |
|
jvoung (off chromium)
2015/05/31 17:27:56
"Fuse ... Arithmetic or Cast..." but may need to r
Jim Stichnoth
2015/06/01 06:35:12
Added a separate description for Cast.
|
| // following situations: |
| @@ -3979,30 +3992,46 @@ void TargetX8632::lowerLoad(const InstLoad *Inst) { |
| // load instruction's dest variable, and that instruction ends that |
| // variable's live range, then make the substitution. Deal with |
| // commutativity optimization in the arithmetic instruction lowering. |
| - InstArithmetic *NewArith = nullptr; |
| - if (InstArithmetic *Arith = |
| - llvm::dyn_cast_or_null<InstArithmetic>(Context.getNextInst())) { |
| - Variable *DestLoad = Inst->getDest(); |
| - Variable *Src0Arith = llvm::dyn_cast<Variable>(Arith->getSrc(0)); |
| - Variable *Src1Arith = llvm::dyn_cast<Variable>(Arith->getSrc(1)); |
| - if (Src1Arith == DestLoad && Arith->isLastUse(Src1Arith) && |
| - DestLoad != Src0Arith) { |
| - NewArith = InstArithmetic::create(Func, Arith->getOp(), Arith->getDest(), |
| - Arith->getSrc(0), Src0); |
| - } else if (Src0Arith == DestLoad && Arith->isCommutative() && |
| - Arith->isLastUse(Src0Arith) && DestLoad != Src1Arith) { |
| - NewArith = InstArithmetic::create(Func, Arith->getOp(), Arith->getDest(), |
| - Arith->getSrc(1), Src0); |
| - } |
| - if (NewArith) { |
| - Arith->setDeleted(); |
| - Context.advanceNext(); |
| - lowerArithmetic(NewArith); |
| - return; |
| + // |
| + // TODO(stichnot): Do load fusing as a separate pass. Run it before |
| + // the bool folding pass. Modify Ice::Inst to allow src operands to |
| + // be replaced, including updating Inst::LiveRangesEnded, to avoid |
| + // having to manually mostly clone each instruction type. |
| + Inst *NextInst = Context.getNextInst(); |
| + Variable *DestLoad = Load->getDest(); |
| + if (NextInst && NextInst->isLastUse(DestLoad)) { |
| + if (auto *Arith = llvm::dyn_cast<InstArithmetic>(NextInst)) { |
| + InstArithmetic *NewArith = nullptr; |
| + Variable *Src0Arith = llvm::dyn_cast<Variable>(Arith->getSrc(0)); |
| + Variable *Src1Arith = llvm::dyn_cast<Variable>(Arith->getSrc(1)); |
| + if (Src1Arith == DestLoad && DestLoad != Src0Arith) { |
| + NewArith = InstArithmetic::create( |
| + Func, Arith->getOp(), Arith->getDest(), Arith->getSrc(0), Src0); |
| + } else if (Src0Arith == DestLoad && Arith->isCommutative() && |
| + DestLoad != Src1Arith) { |
| + NewArith = InstArithmetic::create( |
| + Func, Arith->getOp(), Arith->getDest(), Arith->getSrc(1), Src0); |
| + } |
| + if (NewArith) { |
| + Arith->setDeleted(); |
| + Context.advanceNext(); |
| + lowerArithmetic(NewArith); |
| + return; |
| + } |
| + } else if (auto *Cast = llvm::dyn_cast<InstCast>(NextInst)) { |
| + Variable *Src0Cast = llvm::dyn_cast<Variable>(Cast->getSrc(0)); |
| + if (Src0Cast == DestLoad) { |
| + InstCast *NewCast = |
| + InstCast::create(Func, Cast->getCastKind(), Cast->getDest(), Src0); |
| + Cast->setDeleted(); |
| + Context.advanceNext(); |
| + lowerCast(NewCast); |
| + return; |
| + } |
| } |
| } |
| - InstAssign *Assign = InstAssign::create(Func, Inst->getDest(), Src0); |
| + InstAssign *Assign = InstAssign::create(Func, DestLoad, Src0); |
| lowerAssign(Assign); |
| } |