Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit a0c81f0

Browse files
committed
[FastISel][X86] Refactor constant materialization. NFCI.
Split the constant materialization code into three separate helper functions for Integer-, Floating-Point-, and GlobalValue-Constants. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@215586 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 0474237 commit a0c81f0

File tree

1 file changed

+67
-54
lines changed

1 file changed

+67
-54
lines changed

lib/Target/X86/X86FastISel.cpp

Lines changed: 67 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,9 @@ class X86FastISel final : public FastISel {
135135

136136
bool handleConstantAddresses(const Value *V, X86AddressMode &AM);
137137

138+
unsigned X86MaterializeInt(const ConstantInt *CI, MVT VT);
139+
unsigned X86MaterializeFP(const ConstantFP *CFP, MVT VT);
140+
unsigned X86MaterializeGV(const GlobalValue *GV,MVT VT);
138141
unsigned TargetMaterializeConstant(const Constant *C) override;
139142

140143
unsigned TargetMaterializeAlloca(const AllocaInst *C) override;
@@ -3099,10 +3102,15 @@ X86FastISel::TargetSelectInstruction(const Instruction *I) {
30993102
return false;
31003103
}
31013104

3102-
unsigned X86FastISel::TargetMaterializeConstant(const Constant *C) {
3103-
MVT VT;
3104-
if (!isTypeLegal(C->getType(), VT))
3105+
unsigned X86FastISel::X86MaterializeInt(const ConstantInt *CI, MVT VT) {
3106+
if (VT > MVT::i64)
31053107
return 0;
3108+
return FastEmit_i(VT, VT, ISD::Constant, CI->getZExtValue());
3109+
}
3110+
3111+
unsigned X86FastISel::X86MaterializeFP(const ConstantFP *CFP, MVT VT) {
3112+
if (CFP->isNullValue())
3113+
return TargetMaterializeFloatZero(CFP);
31063114

31073115
// Can't handle alternate code models yet.
31083116
if (TM.getCodeModel() != CodeModel::Small)
@@ -3113,23 +3121,6 @@ unsigned X86FastISel::TargetMaterializeConstant(const Constant *C) {
31133121
const TargetRegisterClass *RC = nullptr;
31143122
switch (VT.SimpleTy) {
31153123
default: return 0;
3116-
case MVT::i8:
3117-
Opc = X86::MOV8rm;
3118-
RC = &X86::GR8RegClass;
3119-
break;
3120-
case MVT::i16:
3121-
Opc = X86::MOV16rm;
3122-
RC = &X86::GR16RegClass;
3123-
break;
3124-
case MVT::i32:
3125-
Opc = X86::MOV32rm;
3126-
RC = &X86::GR32RegClass;
3127-
break;
3128-
case MVT::i64:
3129-
// Must be in x86-64 mode.
3130-
Opc = X86::MOV64rm;
3131-
RC = &X86::GR64RegClass;
3132-
break;
31333124
case MVT::f32:
31343125
if (X86ScalarSSEf32) {
31353126
Opc = Subtarget->hasAVX() ? X86::VMOVSSrm : X86::MOVSSrm;
@@ -3153,39 +3144,11 @@ unsigned X86FastISel::TargetMaterializeConstant(const Constant *C) {
31533144
return 0;
31543145
}
31553146

3156-
// Materialize addresses with LEA/MOV instructions.
3157-
if (isa<GlobalValue>(C)) {
3158-
X86AddressMode AM;
3159-
if (X86SelectAddress(C, AM)) {
3160-
// If the expression is just a basereg, then we're done, otherwise we need
3161-
// to emit an LEA.
3162-
if (AM.BaseType == X86AddressMode::RegBase &&
3163-
AM.IndexReg == 0 && AM.Disp == 0 && AM.GV == nullptr)
3164-
return AM.Base.Reg;
3165-
3166-
unsigned ResultReg = createResultReg(RC);
3167-
if (TM.getRelocationModel() == Reloc::Static &&
3168-
TLI.getPointerTy() == MVT::i64) {
3169-
// The displacement code be more than 32 bits away so we need to use
3170-
// an instruction with a 64 bit immediate
3171-
Opc = X86::MOV64ri;
3172-
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
3173-
TII.get(Opc), ResultReg).addGlobalAddress(cast<GlobalValue>(C));
3174-
} else {
3175-
Opc = TLI.getPointerTy() == MVT::i32 ? X86::LEA32r : X86::LEA64r;
3176-
addFullAddress(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
3177-
TII.get(Opc), ResultReg), AM);
3178-
}
3179-
return ResultReg;
3180-
}
3181-
return 0;
3182-
}
3183-
31843147
// MachineConstantPool wants an explicit alignment.
3185-
unsigned Align = DL.getPrefTypeAlignment(C->getType());
3148+
unsigned Align = DL.getPrefTypeAlignment(CFP->getType());
31863149
if (Align == 0) {
3187-
// Alignment of vector types. FIXME!
3188-
Align = DL.getTypeAllocSize(C->getType());
3150+
// Alignment of vector types. FIXME!
3151+
Align = DL.getTypeAllocSize(CFP->getType());
31893152
}
31903153

31913154
// x86-32 PIC requires a PIC base register for constant pools.
@@ -3203,15 +3166,65 @@ unsigned X86FastISel::TargetMaterializeConstant(const Constant *C) {
32033166
}
32043167

32053168
// Create the load from the constant pool.
3206-
unsigned MCPOffset = MCP.getConstantPoolIndex(C, Align);
3169+
unsigned CPI = MCP.getConstantPoolIndex(CFP, Align);
32073170
unsigned ResultReg = createResultReg(RC);
3171+
32083172
addConstantPoolReference(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
32093173
TII.get(Opc), ResultReg),
3210-
MCPOffset, PICBase, OpFlag);
3211-
3174+
CPI, PICBase, OpFlag);
32123175
return ResultReg;
32133176
}
32143177

3178+
unsigned X86FastISel::X86MaterializeGV(const GlobalValue *GV, MVT VT) {
3179+
// Can't handle alternate code models yet.
3180+
if (TM.getCodeModel() != CodeModel::Small)
3181+
return 0;
3182+
3183+
// Materialize addresses with LEA/MOV instructions.
3184+
X86AddressMode AM;
3185+
if (X86SelectAddress(GV, AM)) {
3186+
// If the expression is just a basereg, then we're done, otherwise we need
3187+
// to emit an LEA.
3188+
if (AM.BaseType == X86AddressMode::RegBase &&
3189+
AM.IndexReg == 0 && AM.Disp == 0 && AM.GV == nullptr)
3190+
return AM.Base.Reg;
3191+
3192+
unsigned ResultReg = createResultReg(TLI.getRegClassFor(VT));
3193+
if (TM.getRelocationModel() == Reloc::Static &&
3194+
TLI.getPointerTy() == MVT::i64) {
3195+
// The displacement code could be more than 32 bits away so we need to use
3196+
// an instruction with a 64 bit immediate
3197+
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::MOV64ri),
3198+
ResultReg)
3199+
.addGlobalAddress(GV);
3200+
} else {
3201+
unsigned Opc = TLI.getPointerTy() == MVT::i32 ? X86::LEA32r : X86::LEA64r;
3202+
addFullAddress(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
3203+
TII.get(Opc), ResultReg), AM);
3204+
}
3205+
return ResultReg;
3206+
}
3207+
return 0;
3208+
}
3209+
3210+
unsigned X86FastISel::TargetMaterializeConstant(const Constant *C) {
3211+
EVT CEVT = TLI.getValueType(C->getType(), true);
3212+
3213+
// Only handle simple types.
3214+
if (!CEVT.isSimple())
3215+
return 0;
3216+
MVT VT = CEVT.getSimpleVT();
3217+
3218+
if (const auto *CI = dyn_cast<ConstantInt>(C))
3219+
return X86MaterializeInt(CI, VT);
3220+
else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C))
3221+
return X86MaterializeFP(CFP, VT);
3222+
else if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
3223+
return X86MaterializeGV(GV, VT);
3224+
3225+
return 0;
3226+
}
3227+
32153228
unsigned X86FastISel::TargetMaterializeAlloca(const AllocaInst *C) {
32163229
// Fail on dynamic allocas. At this point, getRegForValue has already
32173230
// checked its CSE maps, so if we're here trying to handle a dynamic

0 commit comments

Comments
 (0)