llvm.org GIT mirror llvm / f1715a3
[GlobalISel] Refactor Legalizer helpers for libcalls We used to have a helper that replaced an instruction with a libcall. That turns out to be too aggressive, since sometimes we need to replace the instruction with at least two libcalls. Therefore, change our existing helper to only create the libcall and leave the instruction removal as a separate step. Also rename the helper accordingly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307149 91177308-0d34-0410-b5e6-96231b3b80d8 Diana Picus 3 years ago
3 changed file(s) with 35 addition(s) and 26 deletion(s). Raw diff Collapse all Expand all
100100 const LegalizerInfo &LI;
101101 };
102102
103 /// Helper function that replaces \p MI with a libcall.
103 /// Helper function that creates the given libcall.
104104 LegalizerHelper::LegalizeResult
105 replaceWithLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder,
106 RTLIB::Libcall Libcall, const CallLowering::ArgInfo &Result,
107 ArrayRef Args);
105 createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall,
106 const CallLowering::ArgInfo &Result,
107 ArrayRef Args);
108108
109109 } // End namespace llvm.
110110
9898 llvm_unreachable("Unknown libcall function");
9999 }
100100
101 LegalizerHelper::LegalizeResult llvm::replaceWithLibcall(
102 MachineInstr &MI, MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall,
103 const CallLowering::ArgInfo &Result, ArrayRef Args) {
101 LegalizerHelper::LegalizeResult
102 llvm::createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall,
103 const CallLowering::ArgInfo &Result,
104 ArrayRef Args) {
104105 auto &CLI = *MIRBuilder.getMF().getSubtarget().getCallLowering();
105106 auto &TLI = *MIRBuilder.getMF().getSubtarget().getTargetLowering();
106107 const char *Name = TLI.getLibcallName(Libcall);
107108 MIRBuilder.getMF().getFrameInfo().setHasCalls(true);
108 MIRBuilder.setInstr(MI);
109109 if (!CLI.lowerCall(MIRBuilder, TLI.getLibcallCallingConv(Libcall),
110110 MachineOperand::CreateES(Name), Result, Args))
111111 return LegalizerHelper::UnableToLegalize;
112
113 // We're about to remove MI, so move the insert point after it.
114 MIRBuilder.setInsertPt(MIRBuilder.getMBB(),
115 std::next(MIRBuilder.getInsertPt()));
116
117 MI.eraseFromParent();
118112 return LegalizerHelper::Legalized;
119113 }
120114
122116 simpleLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, unsigned Size,
123117 Type *OpType) {
124118 auto Libcall = getRTLibDesc(MI.getOpcode(), Size);
125 return replaceWithLibcall(MI, MIRBuilder, Libcall,
126 {MI.getOperand(0).getReg(), OpType},
127 {{MI.getOperand(1).getReg(), OpType},
128 {MI.getOperand(2).getReg(), OpType}});
119 return createLibcall(MIRBuilder, Libcall, {MI.getOperand(0).getReg(), OpType},
120 {{MI.getOperand(1).getReg(), OpType},
121 {MI.getOperand(2).getReg(), OpType}});
129122 }
130123
131124 LegalizerHelper::LegalizeResult
133126 LLT LLTy = MRI.getType(MI.getOperand(0).getReg());
134127 unsigned Size = LLTy.getSizeInBits();
135128 auto &Ctx = MIRBuilder.getMF().getFunction()->getContext();
129
130 MIRBuilder.setInstr(MI);
136131
137132 switch (MI.getOpcode()) {
138133 default:
142137 case TargetOpcode::G_SREM:
143138 case TargetOpcode::G_UREM: {
144139 Type *HLTy = Type::getInt32Ty(Ctx);
145 return simpleLibcall(MI, MIRBuilder, Size, HLTy);
140 auto Status = simpleLibcall(MI, MIRBuilder, Size, HLTy);
141 if (Status != Legalized)
142 return Status;
143 break;
146144 }
147145 case TargetOpcode::G_FADD:
148146 case TargetOpcode::G_FPOW:
149147 case TargetOpcode::G_FREM: {
150148 Type *HLTy = Size == 64 ? Type::getDoubleTy(Ctx) : Type::getFloatTy(Ctx);
151 return simpleLibcall(MI, MIRBuilder, Size, HLTy);
152 }
153 }
149 auto Status = simpleLibcall(MI, MIRBuilder, Size, HLTy);
150 if (Status != Legalized)
151 return Status;
152 break;
153 }
154 }
155
156 MI.eraseFromParent();
157 return Legalized;
154158 }
155159
156160 LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI,
118118 MachineIRBuilder &MIRBuilder) const {
119119 using namespace TargetOpcode;
120120
121 MIRBuilder.setInstr(MI);
122
121123 switch (MI.getOpcode()) {
122124 default:
123125 return false;
139141 auto RetVal = MRI.createGenericVirtualRegister(
140142 getLLTForType(*RetTy, MIRBuilder.getMF().getDataLayout()));
141143
142 auto Status = replaceWithLibcall(MI, MIRBuilder, Libcall, {RetVal, RetTy},
143 {{MI.getOperand(1).getReg(), ArgTy},
144 {MI.getOperand(2).getReg(), ArgTy}});
144 auto Status = createLibcall(MIRBuilder, Libcall, {RetVal, RetTy},
145 {{MI.getOperand(1).getReg(), ArgTy},
146 {MI.getOperand(2).getReg(), ArgTy}});
145147 if (Status != LegalizerHelper::Legalized)
146148 return false;
147149
152154 {MRI.createGenericVirtualRegister(LLT::scalar(32)), OriginalResult},
153155 RetVal);
154156
155 return LegalizerHelper::Legalized;
157 break;
156158 }
157159 }
160
161 MI.eraseFromParent();
162 return true;
158163 }