I->addAttribute(AttributeList::FunctionIndex, Attribute::StrictFP);
}
+ void setDefaultOperandBundles(ArrayRef<OperandBundleDef> OpBundles) {
+ DefaultOperandBundles = OpBundles;
+ }
+
//===--------------------------------------------------------------------===//
// RAII helpers.
//===--------------------------------------------------------------------===//
}
};
+ // RAII object that stores the current default operand bundles and restores
+ // them when the object is destroyed.
+ class OperandBundlesGuard {
+ IRBuilderBase &Builder;
+ ArrayRef<OperandBundleDef> DefaultOperandBundles;
+
+ public:
+ OperandBundlesGuard(IRBuilderBase &B)
+ : Builder(B), DefaultOperandBundles(B.DefaultOperandBundles) {}
+
+ OperandBundlesGuard(const OperandBundlesGuard &) = delete;
+ OperandBundlesGuard &operator=(const OperandBundlesGuard &) = delete;
+
+ ~OperandBundlesGuard() {
+ Builder.DefaultOperandBundles = DefaultOperandBundles;
+ }
+ };
+
+
//===--------------------------------------------------------------------===//
// Miscellaneous creation methods.
//===--------------------------------------------------------------------===//
/// optimal value to replace the instruction with or 0 if a more
/// optimal form can't be found.
/// The call must not be an indirect call.
- Value *optimizeCall(CallInst *CI);
+ Value *optimizeCall(CallInst *CI, IRBuilderBase &B);
private:
Value *optimizeMemCpyChk(CallInst *CI, IRBuilderBase &B);
/// other instructions that use the given instruction were modified
/// and the given instruction is dead.
/// The call must not be an indirect call.
- Value *optimizeCall(CallInst *CI);
+ Value *optimizeCall(CallInst *CI, IRBuilderBase &B);
private:
// String and Memory Library Call Optimizations
}
}
-Value *LibCallSimplifier::optimizeCall(CallInst *CI) {
+Value *LibCallSimplifier::optimizeCall(CallInst *CI, IRBuilderBase &Builder) {
// TODO: Split out the code below that operates on FP calls so that
// we can all non-FP calls with the StrictFP attribute to be
// optimized.
LibFunc Func;
Function *Callee = CI->getCalledFunction();
+ bool isCallingConvC = isCallingConvCCompatible(CI);
SmallVector<OperandBundleDef, 2> OpBundles;
CI->getOperandBundlesAsDefs(OpBundles);
- IRBuilder<> Builder(CI, /*FPMathTag=*/nullptr, OpBundles);
- bool isCallingConvC = isCallingConvCCompatible(CI);
+
+ IRBuilderBase::OperandBundlesGuard Guard(Builder);
+ Builder.setDefaultOperandBundles(OpBundles);
// Command-line parameter overrides instruction attribute.
// This can't be moved to optimizeFloatingPointLibCall() because it may be
}
// Also try to simplify calls to fortified library functions.
- if (Value *SimplifiedFortifiedCI = FortifiedSimplifier.optimizeCall(CI)) {
+ if (Value *SimplifiedFortifiedCI =
+ FortifiedSimplifier.optimizeCall(CI, Builder)) {
// Try to further simplify the result.
CallInst *SimplifiedCI = dyn_cast<CallInst>(SimplifiedFortifiedCI);
if (SimplifiedCI && SimplifiedCI->getCalledFunction()) {
// their uses analyzed.
replaceAllUsesWith(CI, SimplifiedCI);
- // Use an IR Builder from SimplifiedCI if available instead of CI
- // to guarantee we reach all uses we might replace later on.
- IRBuilder<> TmpBuilder(SimplifiedCI);
- if (Value *V = optimizeStringMemoryLibCall(SimplifiedCI, TmpBuilder)) {
+ // Set insertion point to SimplifiedCI to guarantee we reach all uses
+ // we might replace later on.
+ IRBuilderBase::InsertPointGuard Guard(Builder);
+ Builder.SetInsertPoint(SimplifiedCI);
+ if (Value *V = optimizeStringMemoryLibCall(SimplifiedCI, Builder)) {
// If we were able to further simplify, remove the now redundant call.
substituteInParent(SimplifiedCI, V);
return V;
return nullptr;
}
-Value *FortifiedLibCallSimplifier::optimizeCall(CallInst *CI) {
+Value *FortifiedLibCallSimplifier::optimizeCall(CallInst *CI,
+ IRBuilderBase &Builder) {
// FIXME: We shouldn't be changing "nobuiltin" or TLI unavailable calls here.
// Some clang users checked for _chk libcall availability using:
// __has_builtin(__builtin___memcpy_chk)
LibFunc Func;
Function *Callee = CI->getCalledFunction();
+ bool isCallingConvC = isCallingConvCCompatible(CI);
SmallVector<OperandBundleDef, 2> OpBundles;
CI->getOperandBundlesAsDefs(OpBundles);
- IRBuilder<> Builder(CI, /*FPMathTag=*/nullptr, OpBundles);
- bool isCallingConvC = isCallingConvCCompatible(CI);
+
+ IRBuilderBase::OperandBundlesGuard Guard(Builder);
+ Builder.setDefaultOperandBundles(OpBundles);
// First, check that this is a known library functions and that the prototype
// is correct.