Index: src/IceTargetLoweringX8632.cpp |
diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp |
index f66a364dabc6ff68ab8e9439ff1c7fad454aa15a..e626a7179f78c540a57cfb85903a9fdc646dd681 100644 |
--- a/src/IceTargetLoweringX8632.cpp |
+++ b/src/IceTargetLoweringX8632.cpp |
@@ -322,6 +322,7 @@ void TargetX8632::translateO2() { |
// Address mode optimization. |
Timer T_doAddressOpt; |
+ Func->getVMetadata()->init(); |
Func->doAddressOpt(); |
T_doAddressOpt.printElapsedUs(Context, "doAddressOpt()"); |
@@ -470,10 +471,13 @@ Variable *TargetX8632::getPhysicalRegister(SizeT RegNum) { |
assert(RegNum < PhysicalRegisters.size()); |
Variable *Reg = PhysicalRegisters[RegNum]; |
if (Reg == NULL) { |
- CfgNode *Node = NULL; // NULL means multi-block lifetime |
- Reg = Func->makeVariable(IceType_i32, Node); |
+ Reg = Func->makeVariable(IceType_i32); |
Reg->setRegNum(RegNum); |
PhysicalRegisters[RegNum] = Reg; |
+ // Specially mark esp as an "argument" so that it is considered |
+ // live upon function entry. |
+ if (RegNum == RegX8632::Reg_esp) |
+ Reg->setIsArg(); |
} |
return Reg; |
} |
@@ -505,10 +509,8 @@ IceString TargetX8632::getRegName(SizeT RegNum, Type Ty) const { |
} |
} |
-void TargetX8632::emitVariable(const Variable *Var, const Cfg *Func) const { |
+void TargetX8632::emitVariable(const Variable *Var) const { |
Ostream &Str = Ctx->getStrEmit(); |
- assert(Var->getLocalUseNode() == NULL || |
- Var->getLocalUseNode() == Func->getCurrentNode()); |
if (Var->hasReg()) { |
Str << getRegName(Var->getRegNum(), Var->getType()); |
return; |
@@ -548,11 +550,10 @@ void TargetX8632::lowerArguments() { |
int32_t RegNum = RegX8632::Reg_xmm0 + NumXmmArgs; |
++NumXmmArgs; |
IceString Name = "home_reg:" + Arg->getName(); |
- const CfgNode *DefNode = NULL; |
- Variable *RegisterArg = Func->makeVariable(Ty, DefNode, Name); |
+ Variable *RegisterArg = Func->makeVariable(Ty, Name); |
RegisterArg->setRegNum(RegNum); |
- RegisterArg->setIsArg(Func); |
- Arg->setIsArg(Func, false); |
+ RegisterArg->setIsArg(); |
+ Arg->setIsArg(false); |
Args[I] = RegisterArg; |
Context.insert(InstAssign::create(Func, Arg, RegisterArg)); |
@@ -675,6 +676,7 @@ void TargetX8632::addProlog(CfgNode *Node) { |
size_t InArgsSizeBytes = 0; |
size_t PreservedRegsSizeBytes = 0; |
SpillAreaSizeBytes = 0; |
+ const VariablesMetadata *VMetadata = Func->getVMetadata(); |
Context.init(Node); |
Context.setInsertPoint(Context.getCur()); |
@@ -743,11 +745,11 @@ void TargetX8632::addProlog(CfgNode *Node) { |
size_t Increment = typeWidthInBytesOnStack(Var->getType()); |
if (!SpillAreaAlignmentBytes) |
SpillAreaAlignmentBytes = Increment; |
- if (SimpleCoalescing) { |
- if (Var->isMultiblockLife()) { |
+ if (SimpleCoalescing && VMetadata->isTracked(Var)) { |
+ if (VMetadata->isMultiBlock(Var)) { |
GlobalsSize += Increment; |
} else { |
- SizeT NodeIndex = Var->getLocalUseNode()->getIndex(); |
+ SizeT NodeIndex = VMetadata->getLocalUseNode(Var)->getIndex(); |
LocalsSize[NodeIndex] += Increment; |
if (LocalsSize[NodeIndex] > SpillAreaSizeBytes) |
SpillAreaSizeBytes = LocalsSize[NodeIndex]; |
@@ -852,12 +854,12 @@ void TargetX8632::addProlog(CfgNode *Node) { |
I != E; ++I) { |
Variable *Var = *I; |
size_t Increment = typeWidthInBytesOnStack(Var->getType()); |
- if (SimpleCoalescing) { |
- if (Var->isMultiblockLife()) { |
+ if (SimpleCoalescing && VMetadata->isTracked(Var)) { |
+ if (VMetadata->isMultiBlock(Var)) { |
GlobalsSpaceUsed += Increment; |
NextStackOffset = GlobalsSpaceUsed; |
} else { |
- SizeT NodeIndex = Var->getLocalUseNode()->getIndex(); |
+ SizeT NodeIndex = VMetadata->getLocalUseNode(Var)->getIndex(); |
LocalsSize[NodeIndex] += Increment; |
NextStackOffset = SpillAreaPaddingBytes + |
GlobalsAndSubsequentPaddingSize + |
@@ -1035,14 +1037,12 @@ void TargetX8632::split64(Variable *Var) { |
return; |
} |
assert(Hi == NULL); |
- Lo = Func->makeVariable(IceType_i32, Context.getNode(), |
- Var->getName() + "__lo"); |
- Hi = Func->makeVariable(IceType_i32, Context.getNode(), |
- Var->getName() + "__hi"); |
+ Lo = Func->makeVariable(IceType_i32, Var->getName() + "__lo"); |
+ Hi = Func->makeVariable(IceType_i32, Var->getName() + "__hi"); |
Var->setLoHi(Lo, Hi); |
if (Var->getIsArg()) { |
- Lo->setIsArg(Func); |
- Hi->setIsArg(Func); |
+ Lo->setIsArg(); |
+ Hi->setIsArg(); |
} |
} |
@@ -2276,8 +2276,7 @@ void TargetX8632::lowerCast(const InstCast *Inst) { |
Variable *T = NULL; |
// TODO: Should be able to force a spill setup by calling legalize() with |
// Legal_Mem and not Legal_Reg or Legal_Imm. |
- SpillVariable *SpillVar = |
- Func->makeVariable<SpillVariable>(SrcType, Context.getNode()); |
+ SpillVariable *SpillVar = Func->makeVariable<SpillVariable>(SrcType); |
SpillVar->setLinkedTo(Dest); |
Variable *Spill = SpillVar; |
Spill->setWeight(RegWeight::Zero); |
@@ -2294,8 +2293,7 @@ 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, Context.getNode()); |
+ SpillVariable *SpillVar = Func->makeVariable<SpillVariable>(IceType_f64); |
SpillVar->setLinkedTo(llvm::dyn_cast<Variable>(Src0RM)); |
Variable *Spill = SpillVar; |
Spill->setWeight(RegWeight::Zero); |
@@ -2325,8 +2323,7 @@ void TargetX8632::lowerCast(const InstCast *Inst) { |
// t_hi.i32 = b_hi.i32 |
// hi(s.f64) = t_hi.i32 |
// a.f64 = s.f64 |
- SpillVariable *SpillVar = |
- Func->makeVariable<SpillVariable>(IceType_f64, Context.getNode()); |
+ SpillVariable *SpillVar = Func->makeVariable<SpillVariable>(IceType_f64); |
SpillVar->setLinkedTo(Dest); |
Variable *Spill = SpillVar; |
Spill->setWeight(RegWeight::Zero); |
@@ -2349,8 +2346,7 @@ void TargetX8632::lowerCast(const InstCast *Inst) { |
case IceType_v8i1: { |
assert(Src0->getType() == IceType_i8); |
InstCall *Call = makeHelperCall("Sz_bitcast_i8_to_v8i1", Dest, 1); |
- Variable *Src0AsI32 = Func->makeVariable(stackSlotType(), |
- Context.getNode()); |
+ Variable *Src0AsI32 = Func->makeVariable(stackSlotType()); |
// Arguments to functions are required to be at least 32 bits wide. |
lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0)); |
Call->addArg(Src0AsI32); |
@@ -2359,8 +2355,7 @@ void TargetX8632::lowerCast(const InstCast *Inst) { |
case IceType_v16i1: { |
assert(Src0->getType() == IceType_i16); |
InstCall *Call = makeHelperCall("Sz_bitcast_i16_to_v16i1", Dest, 1); |
- Variable *Src0AsI32 = Func->makeVariable(stackSlotType(), |
- Context.getNode()); |
+ Variable *Src0AsI32 = Func->makeVariable(stackSlotType()); |
// Arguments to functions are required to be at least 32 bits wide. |
lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0)); |
Call->addArg(Src0AsI32); |
@@ -2429,7 +2424,7 @@ void TargetX8632::lowerExtractElement(const InstExtractElement *Inst) { |
// |
// TODO(wala): use legalize(SourceVectNotLegalized, Legal_Mem) when |
// support for legalizing to mem is implemented. |
- Variable *Slot = Func->makeVariable(Ty, Context.getNode()); |
+ Variable *Slot = Func->makeVariable(Ty); |
Slot->setWeight(RegWeight::Zero); |
_movp(Slot, legalizeToVar(SourceVectNotLegalized)); |
@@ -2584,8 +2579,8 @@ void TargetX8632::lowerIcmp(const InstIcmp *Inst) { |
NewTy = IceType_v16i8; |
break; |
} |
- Variable *NewSrc0 = Func->makeVariable(NewTy, Context.getNode()); |
- Variable *NewSrc1 = Func->makeVariable(NewTy, Context.getNode()); |
+ Variable *NewSrc0 = Func->makeVariable(NewTy); |
+ Variable *NewSrc1 = Func->makeVariable(NewTy); |
lowerCast(InstCast::create(Func, InstCast::Sext, NewSrc0, Src0)); |
lowerCast(InstCast::create(Func, InstCast::Sext, NewSrc1, Src1)); |
Src0 = NewSrc0; |
@@ -2760,8 +2755,7 @@ void TargetX8632::lowerInsertElement(const InstInsertElement *Inst) { |
if (ElementTy == IceType_i1) { |
// Expand the element to the appropriate size for it to be inserted |
// in the vector. |
- Variable *Expanded = |
- Func->makeVariable(InVectorElementTy, Context.getNode()); |
+ Variable *Expanded = Func->makeVariable(InVectorElementTy); |
InstCast *Cast = InstCast::create(Func, InstCast::Zext, Expanded, |
ElementToInsertNotLegalized); |
lowerCast(Cast); |
@@ -2853,7 +2847,7 @@ void TargetX8632::lowerInsertElement(const InstInsertElement *Inst) { |
// |
// TODO(wala): use legalize(SourceVectNotLegalized, Legal_Mem) when |
// support for legalizing to mem is implemented. |
- Variable *Slot = Func->makeVariable(Ty, Context.getNode()); |
+ Variable *Slot = Func->makeVariable(Ty); |
Slot->setWeight(RegWeight::Zero); |
_movp(Slot, legalizeToVar(SourceVectNotLegalized)); |
@@ -3123,7 +3117,7 @@ void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { |
// wide. |
Operand *ValOp = Instr->getArg(1); |
assert(ValOp->getType() == IceType_i8); |
- Variable *ValExt = Func->makeVariable(stackSlotType(), Context.getNode()); |
+ Variable *ValExt = Func->makeVariable(stackSlotType()); |
lowerCast(InstCast::create(Func, InstCast::Zext, ValExt, ValOp)); |
InstCall *Call = makeHelperCall("memset", NULL, 3); |
Call->addArg(Instr->getArg(0)); |
@@ -3579,17 +3573,18 @@ void dumpAddressOpt(const Cfg *Func, const Variable *Base, |
Str << ", Shift=" << Shift << ", Offset=" << Offset << "\n"; |
} |
-bool matchTransitiveAssign(Variable *&Var, const Inst *&Reason) { |
+bool matchTransitiveAssign(const VariablesMetadata *VMetadata, Variable *&Var, |
+ const Inst *&Reason) { |
// Var originates from Var=SrcVar ==> |
// set Var:=SrcVar |
if (Var == NULL) |
return false; |
- if (const Inst *VarAssign = Var->getDefinition()) { |
+ if (const Inst *VarAssign = VMetadata->getDefinition(Var)) { |
if (llvm::isa<InstAssign>(VarAssign)) { |
Operand *SrcOp = VarAssign->getSrc(0); |
assert(SrcOp); |
if (Variable *SrcVar = llvm::dyn_cast<Variable>(SrcOp)) { |
- if (!SrcVar->getIsMultidef() && |
+ if (!VMetadata->isMultiDef(SrcVar) && |
// TODO: ensure SrcVar stays single-BB |
true) { |
Var = SrcVar; |
@@ -3602,7 +3597,8 @@ bool matchTransitiveAssign(Variable *&Var, const Inst *&Reason) { |
return false; |
} |
-bool matchCombinedBaseIndex(Variable *&Base, Variable *&Index, uint16_t &Shift, |
+bool matchCombinedBaseIndex(const VariablesMetadata *VMetadata, Variable *&Base, |
+ Variable *&Index, uint16_t &Shift, |
const Inst *&Reason) { |
// Index==NULL && Base is Base=Var1+Var2 ==> |
// set Base=Var1, Index=Var2, Shift=0 |
@@ -3610,16 +3606,16 @@ bool matchCombinedBaseIndex(Variable *&Base, Variable *&Index, uint16_t &Shift, |
return false; |
if (Index != NULL) |
return false; |
- const Inst *BaseInst = Base->getDefinition(); |
+ const Inst *BaseInst = VMetadata->getDefinition(Base); |
if (BaseInst == NULL) |
return false; |
if (BaseInst->getSrcSize() < 2) |
return false; |
if (Variable *Var1 = llvm::dyn_cast<Variable>(BaseInst->getSrc(0))) { |
- if (Var1->getIsMultidef()) |
+ if (VMetadata->isMultiDef(Var1)) |
return false; |
if (Variable *Var2 = llvm::dyn_cast<Variable>(BaseInst->getSrc(1))) { |
- if (Var2->getIsMultidef()) |
+ if (VMetadata->isMultiDef(Var2)) |
return false; |
if (isAdd(BaseInst) && |
// TODO: ensure Var1 and Var2 stay single-BB |
@@ -3635,12 +3631,13 @@ bool matchCombinedBaseIndex(Variable *&Base, Variable *&Index, uint16_t &Shift, |
return false; |
} |
-bool matchShiftedIndex(Variable *&Index, uint16_t &Shift, const Inst *&Reason) { |
+bool matchShiftedIndex(const VariablesMetadata *VMetadata, Variable *&Index, |
+ uint16_t &Shift, const Inst *&Reason) { |
// Index is Index=Var*Const && log2(Const)+Shift<=3 ==> |
// Index=Var, Shift+=log2(Const) |
if (Index == NULL) |
return false; |
- const Inst *IndexInst = Index->getDefinition(); |
+ const Inst *IndexInst = VMetadata->getDefinition(Index); |
if (IndexInst == NULL) |
return false; |
if (IndexInst->getSrcSize() < 2) |
@@ -3651,7 +3648,7 @@ bool matchShiftedIndex(Variable *&Index, uint16_t &Shift, const Inst *&Reason) { |
if (ConstantInteger32 *Const = |
llvm::dyn_cast<ConstantInteger32>(ArithInst->getSrc(1))) { |
if (ArithInst->getOp() == InstArithmetic::Mul && |
- !Var->getIsMultidef() && Const->getType() == IceType_i32) { |
+ !VMetadata->isMultiDef(Var) && Const->getType() == IceType_i32) { |
uint64_t Mult = Const->getValue(); |
uint32_t LogMult; |
switch (Mult) { |
@@ -3683,14 +3680,15 @@ bool matchShiftedIndex(Variable *&Index, uint16_t &Shift, const Inst *&Reason) { |
return false; |
} |
-bool matchOffsetBase(Variable *&Base, int32_t &Offset, const Inst *&Reason) { |
+bool matchOffsetBase(const VariablesMetadata *VMetadata, Variable *&Base, |
+ int32_t &Offset, const Inst *&Reason) { |
// Base is Base=Var+Const || Base is Base=Const+Var ==> |
// set Base=Var, Offset+=Const |
// Base is Base=Var-Const ==> |
// set Base=Var, Offset-=Const |
if (Base == NULL) |
return false; |
- const Inst *BaseInst = Base->getDefinition(); |
+ const Inst *BaseInst = VMetadata->getDefinition(Base); |
if (BaseInst == NULL) |
return false; |
if (const InstArithmetic *ArithInst = |
@@ -3709,7 +3707,7 @@ bool matchOffsetBase(Variable *&Base, int32_t &Offset, const Inst *&Reason) { |
Const = llvm::dyn_cast<ConstantInteger32>(ArithInst->getSrc(0)); |
Var = llvm::dyn_cast<Variable>(ArithInst->getSrc(1)); |
} |
- if (Var == NULL || Const == NULL || Var->getIsMultidef()) |
+ if (Var == NULL || Const == NULL || VMetadata->isMultiDef(Var)) |
return false; |
int32_t MoreOffset = IsAdd ? Const->getValue() : -Const->getValue(); |
if (WouldOverflowAdd(Offset, MoreOffset)) |
@@ -3737,17 +3735,18 @@ void computeAddressOpt(Cfg *Func, const Inst *Instr, Variable *&Base, |
// blocks, then don't go further. Alternatively (?), never consider |
// a transformation that would change a variable that is currently |
// *not* live across basic block boundaries into one that *is*. |
- if (Base->isMultiblockLife() /* || Base->getUseCount() > 1*/) |
+ if (Func->getVMetadata()->isMultiBlock(Base) /* || Base->getUseCount() > 1*/) |
return; |
+ const VariablesMetadata *VMetadata = Func->getVMetadata(); |
bool Continue = true; |
while (Continue) { |
const Inst *Reason = NULL; |
- if (matchTransitiveAssign(Base, Reason) || |
- matchTransitiveAssign(Index, Reason) || |
- matchCombinedBaseIndex(Base, Index, Shift, Reason) || |
- matchShiftedIndex(Index, Shift, Reason) || |
- matchOffsetBase(Base, Offset, Reason)) { |
+ if (matchTransitiveAssign(VMetadata, Base, Reason) || |
+ matchTransitiveAssign(VMetadata, Index, Reason) || |
+ matchCombinedBaseIndex(VMetadata, Base, Index, Shift, Reason) || |
+ matchShiftedIndex(VMetadata, Index, Shift, Reason) || |
+ matchOffsetBase(VMetadata, Base, Offset, Reason)) { |
dumpAddressOpt(Func, Base, Index, Shift, Offset, Reason); |
} else { |
Continue = false; |
@@ -3939,7 +3938,7 @@ void TargetX8632::lowerSelect(const InstSelect *Inst) { |
// Sign extend the condition operand if applicable. |
if (SrcTy == IceType_v4f32) { |
// The sext operation takes only integer arguments. |
- Variable *T3 = Func->makeVariable(IceType_v4i32, Context.getNode()); |
+ Variable *T3 = Func->makeVariable(IceType_v4i32); |
lowerCast(InstCast::create(Func, InstCast::Sext, T3, Condition)); |
_movp(T, T3); |
} else if (typeElementType(SrcTy) != IceType_i1) { |
@@ -4070,17 +4069,17 @@ void TargetX8632::scalarizeArithmetic(InstArithmetic::OpKind Kind, |
Constant *Index = Ctx->getConstantInt32(IceType_i32, I); |
// Extract the next two inputs. |
- Variable *Op0 = Func->makeVariable(ElementTy, Context.getNode()); |
+ Variable *Op0 = Func->makeVariable(ElementTy); |
lowerExtractElement(InstExtractElement::create(Func, Op0, Src0, Index)); |
- Variable *Op1 = Func->makeVariable(ElementTy, Context.getNode()); |
+ Variable *Op1 = Func->makeVariable(ElementTy); |
lowerExtractElement(InstExtractElement::create(Func, Op1, Src1, Index)); |
// Perform the arithmetic as a scalar operation. |
- Variable *Res = Func->makeVariable(ElementTy, Context.getNode()); |
+ Variable *Res = Func->makeVariable(ElementTy); |
lowerArithmetic(InstArithmetic::create(Func, Kind, Res, Op0, Op1)); |
// Insert the result into position. |
- Variable *DestT = Func->makeVariable(Ty, Context.getNode()); |
+ Variable *DestT = Func->makeVariable(Ty); |
lowerInsertElement(InstInsertElement::create(Func, DestT, T, Res, Index)); |
T = DestT; |
// TODO(stichnot): Use postLower() in -Om1 mode to avoid buildup of |
@@ -4324,7 +4323,7 @@ OperandX8632Mem *TargetX8632::FormMemoryOperand(Operand *Operand, Type Ty) { |
Variable *TargetX8632::makeReg(Type Type, int32_t RegNum) { |
// There aren't any 64-bit integer registers for x86-32. |
assert(Type != IceType_i64); |
- Variable *Reg = Func->makeVariable(Type, Context.getNode()); |
+ Variable *Reg = Func->makeVariable(Type); |
if (RegNum == Variable::NoRegister) |
Reg->setWeightInfinite(); |
else |