1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-26 04:32:44 +01:00

[IRBuilder] Virtualize IRBuilder

Related llvm-dev thread:
http://lists.llvm.org/pipermail/llvm-dev/2020-February/138951.html

This patch moves the IRBuilder from templating over the constant
folder and inserter towards making both of these virtual.
There are a couple of motivations for this:

1. It's not possible to share code between use-sites that use
different IRBuilder folders/inserters (short of templating the code
and moving it into headers).
2. Methods currently defined on IRBuilderBase (which is not templated)
do not use the custom inserter, resulting in subtle bugs (e.g.
incorrect InstCombine worklist management). It would be possible to
move those into the templated IRBuilder, but...
3. The vast majority of the IRBuilder implementation has to live
in the header, because it depends on the template arguments.
4. We have many unnecessary dependencies on IRBuilder.h,
because it is not easy to forward-declare. (Significant parts of
the backend depend on it via TargetLowering.h, for example.)

This patch addresses the issue by making the following changes:

* IRBuilderDefaultInserter::InsertHelper becomes virtual.
  IRBuilderBase accepts a reference to it.
* IRBuilderFolder is introduced as a virtual base class. It is
 implemented by ConstantFolder (default), NoFolder and TargetFolder.
  IRBuilderBase has a reference to this as well.
* All the logic is moved from IRBuilder to IRBuilderBase. This means
  that methods can in the future replace their IRBuilder<> & uses
  (or other specific IRBuilder types) with IRBuilderBase & and thus
  be usable with different IRBuilders.
* The IRBuilder class is now a thin wrapper around IRBuilderBase.
  Essentially it only stores the folder and inserter and takes care
  of constructing the base builder.

What this patch doesn't do, but should be simple followups after this change:

* Fixing use of the inserter for creation methods originally defined
  on IRBuilderBase.
* Replacing IRBuilder<> uses in arguments with IRBuilderBase, where useful.
* Moving code from the IRBuilder header to the source file.

From the user perspective, these changes should be mostly transparent:
The only thing that consumers using a custom inserted may need to do is
inherit from IRBuilderDefaultInserter publicly and mark their InsertHelper
as public.

Differential Revision: https://reviews.llvm.org/D73835
This commit is contained in:
Nikita Popov 2020-02-01 18:23:36 +01:00
parent 86793686ea
commit f3c97cd987
8 changed files with 438 additions and 243 deletions

View File

@ -22,13 +22,14 @@
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/IRBuilderFolder.h"
namespace llvm {
class DataLayout;
/// TargetFolder - Create constants with target dependent folding.
class TargetFolder {
class TargetFolder final : public IRBuilderFolder {
const DataLayout &DL;
/// Fold - Fold the constant using target specific information.
@ -38,6 +39,8 @@ class TargetFolder {
return C;
}
virtual void anchor();
public:
explicit TargetFolder(const DataLayout &DL) : DL(DL) {}
@ -46,66 +49,70 @@ public:
//===--------------------------------------------------------------------===//
Constant *CreateAdd(Constant *LHS, Constant *RHS,
bool HasNUW = false, bool HasNSW = false) const {
bool HasNUW = false, bool HasNSW = false) const override {
return Fold(ConstantExpr::getAdd(LHS, RHS, HasNUW, HasNSW));
}
Constant *CreateFAdd(Constant *LHS, Constant *RHS) const {
Constant *CreateFAdd(Constant *LHS, Constant *RHS) const override {
return Fold(ConstantExpr::getFAdd(LHS, RHS));
}
Constant *CreateSub(Constant *LHS, Constant *RHS,
bool HasNUW = false, bool HasNSW = false) const {
bool HasNUW = false, bool HasNSW = false) const override {
return Fold(ConstantExpr::getSub(LHS, RHS, HasNUW, HasNSW));
}
Constant *CreateFSub(Constant *LHS, Constant *RHS) const {
Constant *CreateFSub(Constant *LHS, Constant *RHS) const override {
return Fold(ConstantExpr::getFSub(LHS, RHS));
}
Constant *CreateMul(Constant *LHS, Constant *RHS,
bool HasNUW = false, bool HasNSW = false) const {
bool HasNUW = false, bool HasNSW = false) const override {
return Fold(ConstantExpr::getMul(LHS, RHS, HasNUW, HasNSW));
}
Constant *CreateFMul(Constant *LHS, Constant *RHS) const {
Constant *CreateFMul(Constant *LHS, Constant *RHS) const override {
return Fold(ConstantExpr::getFMul(LHS, RHS));
}
Constant *CreateUDiv(Constant *LHS, Constant *RHS, bool isExact = false)const{
Constant *CreateUDiv(Constant *LHS, Constant *RHS,
bool isExact = false) const override {
return Fold(ConstantExpr::getUDiv(LHS, RHS, isExact));
}
Constant *CreateSDiv(Constant *LHS, Constant *RHS, bool isExact = false)const{
Constant *CreateSDiv(Constant *LHS, Constant *RHS,
bool isExact = false) const override {
return Fold(ConstantExpr::getSDiv(LHS, RHS, isExact));
}
Constant *CreateFDiv(Constant *LHS, Constant *RHS) const {
Constant *CreateFDiv(Constant *LHS, Constant *RHS) const override {
return Fold(ConstantExpr::getFDiv(LHS, RHS));
}
Constant *CreateURem(Constant *LHS, Constant *RHS) const {
Constant *CreateURem(Constant *LHS, Constant *RHS) const override {
return Fold(ConstantExpr::getURem(LHS, RHS));
}
Constant *CreateSRem(Constant *LHS, Constant *RHS) const {
Constant *CreateSRem(Constant *LHS, Constant *RHS) const override {
return Fold(ConstantExpr::getSRem(LHS, RHS));
}
Constant *CreateFRem(Constant *LHS, Constant *RHS) const {
Constant *CreateFRem(Constant *LHS, Constant *RHS) const override {
return Fold(ConstantExpr::getFRem(LHS, RHS));
}
Constant *CreateShl(Constant *LHS, Constant *RHS,
bool HasNUW = false, bool HasNSW = false) const {
bool HasNUW = false, bool HasNSW = false) const override {
return Fold(ConstantExpr::getShl(LHS, RHS, HasNUW, HasNSW));
}
Constant *CreateLShr(Constant *LHS, Constant *RHS, bool isExact = false)const{
Constant *CreateLShr(Constant *LHS, Constant *RHS,
bool isExact = false) const override {
return Fold(ConstantExpr::getLShr(LHS, RHS, isExact));
}
Constant *CreateAShr(Constant *LHS, Constant *RHS, bool isExact = false)const{
Constant *CreateAShr(Constant *LHS, Constant *RHS,
bool isExact = false) const override {
return Fold(ConstantExpr::getAShr(LHS, RHS, isExact));
}
Constant *CreateAnd(Constant *LHS, Constant *RHS) const {
Constant *CreateAnd(Constant *LHS, Constant *RHS) const override {
return Fold(ConstantExpr::getAnd(LHS, RHS));
}
Constant *CreateOr(Constant *LHS, Constant *RHS) const {
Constant *CreateOr(Constant *LHS, Constant *RHS) const override {
return Fold(ConstantExpr::getOr(LHS, RHS));
}
Constant *CreateXor(Constant *LHS, Constant *RHS) const {
Constant *CreateXor(Constant *LHS, Constant *RHS) const override {
return Fold(ConstantExpr::getXor(LHS, RHS));
}
Constant *CreateBinOp(Instruction::BinaryOps Opc,
Constant *LHS, Constant *RHS) const {
Constant *LHS, Constant *RHS) const override {
return Fold(ConstantExpr::get(Opc, LHS, RHS));
}
@ -114,17 +121,17 @@ public:
//===--------------------------------------------------------------------===//
Constant *CreateNeg(Constant *C,
bool HasNUW = false, bool HasNSW = false) const {
bool HasNUW = false, bool HasNSW = false) const override {
return Fold(ConstantExpr::getNeg(C, HasNUW, HasNSW));
}
Constant *CreateFNeg(Constant *C) const {
Constant *CreateFNeg(Constant *C) const override {
return Fold(ConstantExpr::getFNeg(C));
}
Constant *CreateNot(Constant *C) const {
Constant *CreateNot(Constant *C) const override {
return Fold(ConstantExpr::getNot(C));
}
Constant *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const {
Constant *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const override {
return Fold(ConstantExpr::get(Opc, C));
}
@ -133,33 +140,34 @@ public:
//===--------------------------------------------------------------------===//
Constant *CreateGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Constant *> IdxList) const {
ArrayRef<Constant *> IdxList) const override {
return Fold(ConstantExpr::getGetElementPtr(Ty, C, IdxList));
}
Constant *CreateGetElementPtr(Type *Ty, Constant *C, Constant *Idx) const {
Constant *CreateGetElementPtr(Type *Ty, Constant *C,
Constant *Idx) const override {
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
return Fold(ConstantExpr::getGetElementPtr(Ty, C, Idx));
}
Constant *CreateGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Value *> IdxList) const {
ArrayRef<Value *> IdxList) const override {
return Fold(ConstantExpr::getGetElementPtr(Ty, C, IdxList));
}
Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Constant *> IdxList) const {
Constant *CreateInBoundsGetElementPtr(
Type *Ty, Constant *C, ArrayRef<Constant *> IdxList) const override {
return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList));
}
Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
Constant *Idx) const {
Constant *Idx) const override {
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, C, Idx));
}
Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Value *> IdxList) const {
Constant *CreateInBoundsGetElementPtr(
Type *Ty, Constant *C, ArrayRef<Value *> IdxList) const override {
return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList));
}
@ -168,54 +176,54 @@ public:
//===--------------------------------------------------------------------===//
Constant *CreateCast(Instruction::CastOps Op, Constant *C,
Type *DestTy) const {
Type *DestTy) const override {
if (C->getType() == DestTy)
return C; // avoid calling Fold
return Fold(ConstantExpr::getCast(Op, C, DestTy));
}
Constant *CreateIntCast(Constant *C, Type *DestTy,
bool isSigned) const {
bool isSigned) const override {
if (C->getType() == DestTy)
return C; // avoid calling Fold
return Fold(ConstantExpr::getIntegerCast(C, DestTy, isSigned));
}
Constant *CreatePointerCast(Constant *C, Type *DestTy) const {
Constant *CreatePointerCast(Constant *C, Type *DestTy) const override {
if (C->getType() == DestTy)
return C; // avoid calling Fold
return Fold(ConstantExpr::getPointerCast(C, DestTy));
}
Constant *CreateFPCast(Constant *C, Type *DestTy) const {
Constant *CreateFPCast(Constant *C, Type *DestTy) const override {
if (C->getType() == DestTy)
return C; // avoid calling Fold
return Fold(ConstantExpr::getFPCast(C, DestTy));
}
Constant *CreateBitCast(Constant *C, Type *DestTy) const {
Constant *CreateBitCast(Constant *C, Type *DestTy) const override {
return CreateCast(Instruction::BitCast, C, DestTy);
}
Constant *CreateIntToPtr(Constant *C, Type *DestTy) const {
Constant *CreateIntToPtr(Constant *C, Type *DestTy) const override {
return CreateCast(Instruction::IntToPtr, C, DestTy);
}
Constant *CreatePtrToInt(Constant *C, Type *DestTy) const {
Constant *CreatePtrToInt(Constant *C, Type *DestTy) const override {
return CreateCast(Instruction::PtrToInt, C, DestTy);
}
Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const {
Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const override {
if (C->getType() == DestTy)
return C; // avoid calling Fold
return Fold(ConstantExpr::getZExtOrBitCast(C, DestTy));
}
Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const {
Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const override {
if (C->getType() == DestTy)
return C; // avoid calling Fold
return Fold(ConstantExpr::getSExtOrBitCast(C, DestTy));
}
Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const {
Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const override {
if (C->getType() == DestTy)
return C; // avoid calling Fold
return Fold(ConstantExpr::getTruncOrBitCast(C, DestTy));
}
Constant *CreatePointerBitCastOrAddrSpaceCast(Constant *C,
Type *DestTy) const {
Type *DestTy) const override {
if (C->getType() == DestTy)
return C; // avoid calling Fold
return Fold(ConstantExpr::getPointerBitCastOrAddrSpaceCast(C, DestTy));
@ -226,11 +234,11 @@ public:
//===--------------------------------------------------------------------===//
Constant *CreateICmp(CmpInst::Predicate P, Constant *LHS,
Constant *RHS) const {
Constant *RHS) const override {
return Fold(ConstantExpr::getCompare(P, LHS, RHS));
}
Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
Constant *RHS) const {
Constant *RHS) const override {
return Fold(ConstantExpr::getCompare(P, LHS, RHS));
}
@ -238,31 +246,32 @@ public:
// Other Instructions
//===--------------------------------------------------------------------===//
Constant *CreateSelect(Constant *C, Constant *True, Constant *False) const {
Constant *CreateSelect(Constant *C, Constant *True,
Constant *False) const override {
return Fold(ConstantExpr::getSelect(C, True, False));
}
Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const {
Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const override {
return Fold(ConstantExpr::getExtractElement(Vec, Idx));
}
Constant *CreateInsertElement(Constant *Vec, Constant *NewElt,
Constant *Idx) const {
Constant *Idx) const override {
return Fold(ConstantExpr::getInsertElement(Vec, NewElt, Idx));
}
Constant *CreateShuffleVector(Constant *V1, Constant *V2,
Constant *Mask) const {
Constant *Mask) const override {
return Fold(ConstantExpr::getShuffleVector(V1, V2, Mask));
}
Constant *CreateExtractValue(Constant *Agg,
ArrayRef<unsigned> IdxList) const {
ArrayRef<unsigned> IdxList) const override {
return Fold(ConstantExpr::getExtractValue(Agg, IdxList));
}
Constant *CreateInsertValue(Constant *Agg, Constant *Val,
ArrayRef<unsigned> IdxList) const {
ArrayRef<unsigned> IdxList) const override {
return Fold(ConstantExpr::getInsertValue(Agg, Val, IdxList));
}
};

View File

@ -20,11 +20,14 @@
#include "llvm/IR/Constants.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/IRBuilderFolder.h"
namespace llvm {
/// ConstantFolder - Create constants with minimum, target independent, folding.
class ConstantFolder {
class ConstantFolder final : public IRBuilderFolder {
virtual void anchor();
public:
explicit ConstantFolder() = default;
@ -33,87 +36,87 @@ public:
//===--------------------------------------------------------------------===//
Constant *CreateAdd(Constant *LHS, Constant *RHS,
bool HasNUW = false, bool HasNSW = false) const {
bool HasNUW = false, bool HasNSW = false) const override {
return ConstantExpr::getAdd(LHS, RHS, HasNUW, HasNSW);
}
Constant *CreateFAdd(Constant *LHS, Constant *RHS) const {
Constant *CreateFAdd(Constant *LHS, Constant *RHS) const override {
return ConstantExpr::getFAdd(LHS, RHS);
}
Constant *CreateSub(Constant *LHS, Constant *RHS,
bool HasNUW = false, bool HasNSW = false) const {
bool HasNUW = false, bool HasNSW = false) const override {
return ConstantExpr::getSub(LHS, RHS, HasNUW, HasNSW);
}
Constant *CreateFSub(Constant *LHS, Constant *RHS) const {
Constant *CreateFSub(Constant *LHS, Constant *RHS) const override {
return ConstantExpr::getFSub(LHS, RHS);
}
Constant *CreateMul(Constant *LHS, Constant *RHS,
bool HasNUW = false, bool HasNSW = false) const {
bool HasNUW = false, bool HasNSW = false) const override {
return ConstantExpr::getMul(LHS, RHS, HasNUW, HasNSW);
}
Constant *CreateFMul(Constant *LHS, Constant *RHS) const {
Constant *CreateFMul(Constant *LHS, Constant *RHS) const override {
return ConstantExpr::getFMul(LHS, RHS);
}
Constant *CreateUDiv(Constant *LHS, Constant *RHS,
bool isExact = false) const {
bool isExact = false) const override {
return ConstantExpr::getUDiv(LHS, RHS, isExact);
}
Constant *CreateSDiv(Constant *LHS, Constant *RHS,
bool isExact = false) const {
bool isExact = false) const override {
return ConstantExpr::getSDiv(LHS, RHS, isExact);
}
Constant *CreateFDiv(Constant *LHS, Constant *RHS) const {
Constant *CreateFDiv(Constant *LHS, Constant *RHS) const override {
return ConstantExpr::getFDiv(LHS, RHS);
}
Constant *CreateURem(Constant *LHS, Constant *RHS) const {
Constant *CreateURem(Constant *LHS, Constant *RHS) const override {
return ConstantExpr::getURem(LHS, RHS);
}
Constant *CreateSRem(Constant *LHS, Constant *RHS) const {
Constant *CreateSRem(Constant *LHS, Constant *RHS) const override {
return ConstantExpr::getSRem(LHS, RHS);
}
Constant *CreateFRem(Constant *LHS, Constant *RHS) const {
Constant *CreateFRem(Constant *LHS, Constant *RHS) const override {
return ConstantExpr::getFRem(LHS, RHS);
}
Constant *CreateShl(Constant *LHS, Constant *RHS,
bool HasNUW = false, bool HasNSW = false) const {
bool HasNUW = false, bool HasNSW = false) const override {
return ConstantExpr::getShl(LHS, RHS, HasNUW, HasNSW);
}
Constant *CreateLShr(Constant *LHS, Constant *RHS,
bool isExact = false) const {
bool isExact = false) const override {
return ConstantExpr::getLShr(LHS, RHS, isExact);
}
Constant *CreateAShr(Constant *LHS, Constant *RHS,
bool isExact = false) const {
bool isExact = false) const override {
return ConstantExpr::getAShr(LHS, RHS, isExact);
}
Constant *CreateAnd(Constant *LHS, Constant *RHS) const {
Constant *CreateAnd(Constant *LHS, Constant *RHS) const override {
return ConstantExpr::getAnd(LHS, RHS);
}
Constant *CreateOr(Constant *LHS, Constant *RHS) const {
Constant *CreateOr(Constant *LHS, Constant *RHS) const override {
return ConstantExpr::getOr(LHS, RHS);
}
Constant *CreateXor(Constant *LHS, Constant *RHS) const {
Constant *CreateXor(Constant *LHS, Constant *RHS) const override {
return ConstantExpr::getXor(LHS, RHS);
}
Constant *CreateBinOp(Instruction::BinaryOps Opc,
Constant *LHS, Constant *RHS) const {
Constant *LHS, Constant *RHS) const override {
return ConstantExpr::get(Opc, LHS, RHS);
}
@ -122,19 +125,19 @@ public:
//===--------------------------------------------------------------------===//
Constant *CreateNeg(Constant *C,
bool HasNUW = false, bool HasNSW = false) const {
bool HasNUW = false, bool HasNSW = false) const override {
return ConstantExpr::getNeg(C, HasNUW, HasNSW);
}
Constant *CreateFNeg(Constant *C) const {
Constant *CreateFNeg(Constant *C) const override {
return ConstantExpr::getFNeg(C);
}
Constant *CreateNot(Constant *C) const {
Constant *CreateNot(Constant *C) const override {
return ConstantExpr::getNot(C);
}
Constant *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const {
Constant *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const override {
return ConstantExpr::get(Opc, C);
}
@ -143,11 +146,12 @@ public:
//===--------------------------------------------------------------------===//
Constant *CreateGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Constant *> IdxList) const {
ArrayRef<Constant *> IdxList) const override {
return ConstantExpr::getGetElementPtr(Ty, C, IdxList);
}
Constant *CreateGetElementPtr(Type *Ty, Constant *C, Constant *Idx) const {
Constant *CreateGetElementPtr(Type *Ty, Constant *C,
Constant *Idx) const override {
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
@ -155,25 +159,25 @@ public:
}
Constant *CreateGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Value *> IdxList) const {
ArrayRef<Value *> IdxList) const override {
return ConstantExpr::getGetElementPtr(Ty, C, IdxList);
}
Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Constant *> IdxList) const {
Constant *CreateInBoundsGetElementPtr(
Type *Ty, Constant *C, ArrayRef<Constant *> IdxList) const override {
return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList);
}
Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
Constant *Idx) const {
Constant *Idx) const override {
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
return ConstantExpr::getInBoundsGetElementPtr(Ty, C, Idx);
}
Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Value *> IdxList) const {
Constant *CreateInBoundsGetElementPtr(
Type *Ty, Constant *C, ArrayRef<Value *> IdxList) const override {
return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList);
}
@ -182,49 +186,49 @@ public:
//===--------------------------------------------------------------------===//
Constant *CreateCast(Instruction::CastOps Op, Constant *C,
Type *DestTy) const {
Type *DestTy) const override {
return ConstantExpr::getCast(Op, C, DestTy);
}
Constant *CreatePointerCast(Constant *C, Type *DestTy) const {
Constant *CreatePointerCast(Constant *C, Type *DestTy) const override {
return ConstantExpr::getPointerCast(C, DestTy);
}
Constant *CreatePointerBitCastOrAddrSpaceCast(Constant *C,
Type *DestTy) const {
Type *DestTy) const override {
return ConstantExpr::getPointerBitCastOrAddrSpaceCast(C, DestTy);
}
Constant *CreateIntCast(Constant *C, Type *DestTy,
bool isSigned) const {
bool isSigned) const override {
return ConstantExpr::getIntegerCast(C, DestTy, isSigned);
}
Constant *CreateFPCast(Constant *C, Type *DestTy) const {
Constant *CreateFPCast(Constant *C, Type *DestTy) const override {
return ConstantExpr::getFPCast(C, DestTy);
}
Constant *CreateBitCast(Constant *C, Type *DestTy) const {
Constant *CreateBitCast(Constant *C, Type *DestTy) const override {
return CreateCast(Instruction::BitCast, C, DestTy);
}
Constant *CreateIntToPtr(Constant *C, Type *DestTy) const {
Constant *CreateIntToPtr(Constant *C, Type *DestTy) const override {
return CreateCast(Instruction::IntToPtr, C, DestTy);
}
Constant *CreatePtrToInt(Constant *C, Type *DestTy) const {
Constant *CreatePtrToInt(Constant *C, Type *DestTy) const override {
return CreateCast(Instruction::PtrToInt, C, DestTy);
}
Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const {
Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const override {
return ConstantExpr::getZExtOrBitCast(C, DestTy);
}
Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const {
Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const override {
return ConstantExpr::getSExtOrBitCast(C, DestTy);
}
Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const {
Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const override {
return ConstantExpr::getTruncOrBitCast(C, DestTy);
}
@ -233,12 +237,12 @@ public:
//===--------------------------------------------------------------------===//
Constant *CreateICmp(CmpInst::Predicate P, Constant *LHS,
Constant *RHS) const {
Constant *RHS) const override {
return ConstantExpr::getCompare(P, LHS, RHS);
}
Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
Constant *RHS) const {
Constant *RHS) const override {
return ConstantExpr::getCompare(P, LHS, RHS);
}
@ -246,31 +250,32 @@ public:
// Other Instructions
//===--------------------------------------------------------------------===//
Constant *CreateSelect(Constant *C, Constant *True, Constant *False) const {
Constant *CreateSelect(Constant *C, Constant *True,
Constant *False) const override {
return ConstantExpr::getSelect(C, True, False);
}
Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const {
Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const override {
return ConstantExpr::getExtractElement(Vec, Idx);
}
Constant *CreateInsertElement(Constant *Vec, Constant *NewElt,
Constant *Idx) const {
Constant *Idx) const override {
return ConstantExpr::getInsertElement(Vec, NewElt, Idx);
}
Constant *CreateShuffleVector(Constant *V1, Constant *V2,
Constant *Mask) const {
Constant *Mask) const override {
return ConstantExpr::getShuffleVector(V1, V2, Mask);
}
Constant *CreateExtractValue(Constant *Agg,
ArrayRef<unsigned> IdxList) const {
ArrayRef<unsigned> IdxList) const override {
return ConstantExpr::getExtractValue(Agg, IdxList);
}
Constant *CreateInsertValue(Constant *Agg, Constant *Val,
ArrayRef<unsigned> IdxList) const {
ArrayRef<unsigned> IdxList) const override {
return ConstantExpr::getInsertValue(Agg, Val, IdxList);
}
};

View File

@ -59,9 +59,12 @@ class Use;
///
/// By default, this inserts the instruction at the insertion point.
class IRBuilderDefaultInserter {
protected:
void InsertHelper(Instruction *I, const Twine &Name,
BasicBlock *BB, BasicBlock::iterator InsertPt) const {
virtual void anchor();
public:
virtual void InsertHelper(Instruction *I, const Twine &Name,
BasicBlock *BB,
BasicBlock::iterator InsertPt) const {
if (BB) BB->getInstList().insert(InsertPt, I);
I->setName(Name);
}
@ -69,16 +72,17 @@ protected:
/// Provides an 'InsertHelper' that calls a user-provided callback after
/// performing the default insertion.
class IRBuilderCallbackInserter : IRBuilderDefaultInserter {
class IRBuilderCallbackInserter : public IRBuilderDefaultInserter {
std::function<void(Instruction *)> Callback;
virtual void anchor();
public:
IRBuilderCallbackInserter(std::function<void(Instruction *)> Callback)
: Callback(std::move(Callback)) {}
protected:
void InsertHelper(Instruction *I, const Twine &Name,
BasicBlock *BB, BasicBlock::iterator InsertPt) const {
BasicBlock *BB,
BasicBlock::iterator InsertPt) const override {
IRBuilderDefaultInserter::InsertHelper(I, Name, BB, InsertPt);
Callback(I);
}
@ -92,6 +96,8 @@ protected:
BasicBlock *BB;
BasicBlock::iterator InsertPt;
LLVMContext &Context;
const IRBuilderFolder &Folder;
const IRBuilderDefaultInserter &Inserter;
MDNode *DefaultFPMathTag;
FastMathFlags FMF;
@ -103,15 +109,37 @@ protected:
ArrayRef<OperandBundleDef> DefaultOperandBundles;
public:
IRBuilderBase(LLVMContext &context, MDNode *FPMathTag = nullptr,
ArrayRef<OperandBundleDef> OpBundles = None)
: Context(context), DefaultFPMathTag(FPMathTag), IsFPConstrained(false),
IRBuilderBase(LLVMContext &context, const IRBuilderFolder &Folder,
const IRBuilderDefaultInserter &Inserter,
MDNode *FPMathTag, ArrayRef<OperandBundleDef> OpBundles)
: Context(context), Folder(Folder), Inserter(Inserter),
DefaultFPMathTag(FPMathTag), IsFPConstrained(false),
DefaultConstrainedExcept(fp::ebStrict),
DefaultConstrainedRounding(fp::rmDynamic),
DefaultOperandBundles(OpBundles) {
ClearInsertionPoint();
}
/// Insert and return the specified instruction.
template<typename InstTy>
InstTy *Insert(InstTy *I, const Twine &Name = "") const {
Inserter.InsertHelper(I, Name, BB, InsertPt);
SetInstDebugLocation(I);
return I;
}
/// No-op overload to handle constants.
Constant *Insert(Constant *C, const Twine& = "") const {
return C;
}
Value *Insert(Value *V, const Twine& = "") const {
if (Instruction *I = dyn_cast<Instruction>(V))
return Insert(I);
assert(isa<Constant>(V));
return V;
}
//===--------------------------------------------------------------------===//
// Builder configuration methods
//===--------------------------------------------------------------------===//
@ -920,85 +948,7 @@ private:
const Twine &Name = "");
Value *getCastedInt8PtrValue(Value *Ptr);
};
/// This provides a uniform API for creating instructions and inserting
/// them into a basic block: either at the end of a BasicBlock, or at a specific
/// iterator location in a block.
///
/// Note that the builder does not expose the full generality of LLVM
/// instructions. For access to extra instruction properties, use the mutators
/// (e.g. setVolatile) on the instructions after they have been
/// created. Convenience state exists to specify fast-math flags and fp-math
/// tags.
///
/// The first template argument specifies a class to use for creating constants.
/// This defaults to creating minimally folded constants. The second template
/// argument allows clients to specify custom insertion hooks that are called on
/// every newly created insertion.
template <typename T = ConstantFolder,
typename Inserter = IRBuilderDefaultInserter>
class IRBuilder : public IRBuilderBase, public Inserter {
T Folder;
public:
IRBuilder(LLVMContext &C, const T &F, Inserter I = Inserter(),
MDNode *FPMathTag = nullptr,
ArrayRef<OperandBundleDef> OpBundles = None)
: IRBuilderBase(C, FPMathTag, OpBundles), Inserter(std::move(I)),
Folder(F) {}
explicit IRBuilder(LLVMContext &C, MDNode *FPMathTag = nullptr,
ArrayRef<OperandBundleDef> OpBundles = None)
: IRBuilderBase(C, FPMathTag, OpBundles) {}
explicit IRBuilder(BasicBlock *TheBB, const T &F, MDNode *FPMathTag = nullptr,
ArrayRef<OperandBundleDef> OpBundles = None)
: IRBuilderBase(TheBB->getContext(), FPMathTag, OpBundles), Folder(F) {
SetInsertPoint(TheBB);
}
explicit IRBuilder(BasicBlock *TheBB, MDNode *FPMathTag = nullptr,
ArrayRef<OperandBundleDef> OpBundles = None)
: IRBuilderBase(TheBB->getContext(), FPMathTag, OpBundles) {
SetInsertPoint(TheBB);
}
explicit IRBuilder(Instruction *IP, MDNode *FPMathTag = nullptr,
ArrayRef<OperandBundleDef> OpBundles = None)
: IRBuilderBase(IP->getContext(), FPMathTag, OpBundles) {
SetInsertPoint(IP);
}
IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T &F,
MDNode *FPMathTag = nullptr,
ArrayRef<OperandBundleDef> OpBundles = None)
: IRBuilderBase(TheBB->getContext(), FPMathTag, OpBundles), Folder(F) {
SetInsertPoint(TheBB, IP);
}
IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP,
MDNode *FPMathTag = nullptr,
ArrayRef<OperandBundleDef> OpBundles = None)
: IRBuilderBase(TheBB->getContext(), FPMathTag, OpBundles) {
SetInsertPoint(TheBB, IP);
}
/// Get the constant folder being used.
const T &getFolder() { return Folder; }
/// Insert and return the specified instruction.
template<typename InstTy>
InstTy *Insert(InstTy *I, const Twine &Name = "") const {
this->InsertHelper(I, Name, BB, InsertPt);
this->SetInstDebugLocation(I);
return I;
}
/// No-op overload to handle constants.
Constant *Insert(Constant *C, const Twine& = "") const {
return C;
}
//===--------------------------------------------------------------------===//
// Instruction creation methods: Terminators
@ -2976,6 +2926,79 @@ public:
}
};
/// This provides a uniform API for creating instructions and inserting
/// them into a basic block: either at the end of a BasicBlock, or at a specific
/// iterator location in a block.
///
/// Note that the builder does not expose the full generality of LLVM
/// instructions. For access to extra instruction properties, use the mutators
/// (e.g. setVolatile) on the instructions after they have been
/// created. Convenience state exists to specify fast-math flags and fp-math
/// tags.
///
/// The first template argument specifies a class to use for creating constants.
/// This defaults to creating minimally folded constants. The second template
/// argument allows clients to specify custom insertion hooks that are called on
/// every newly created insertion.
template <typename FolderTy = ConstantFolder,
typename InserterTy = IRBuilderDefaultInserter>
class IRBuilder : public IRBuilderBase {
private:
FolderTy Folder;
InserterTy Inserter;
public:
IRBuilder(LLVMContext &C, FolderTy Folder, InserterTy Inserter = InserterTy(),
MDNode *FPMathTag = nullptr,
ArrayRef<OperandBundleDef> OpBundles = None)
: IRBuilderBase(C, this->Folder, this->Inserter, FPMathTag, OpBundles),
Folder(Folder), Inserter(Inserter) {}
explicit IRBuilder(LLVMContext &C, MDNode *FPMathTag = nullptr,
ArrayRef<OperandBundleDef> OpBundles = None)
: IRBuilderBase(C, this->Folder, this->Inserter, FPMathTag, OpBundles) {}
explicit IRBuilder(BasicBlock *TheBB, FolderTy Folder,
MDNode *FPMathTag = nullptr,
ArrayRef<OperandBundleDef> OpBundles = None)
: IRBuilderBase(TheBB->getContext(), this->Folder, this->Inserter,
FPMathTag, OpBundles), Folder(Folder) {
SetInsertPoint(TheBB);
}
explicit IRBuilder(BasicBlock *TheBB, MDNode *FPMathTag = nullptr,
ArrayRef<OperandBundleDef> OpBundles = None)
: IRBuilderBase(TheBB->getContext(), this->Folder, this->Inserter,
FPMathTag, OpBundles) {
SetInsertPoint(TheBB);
}
explicit IRBuilder(Instruction *IP, MDNode *FPMathTag = nullptr,
ArrayRef<OperandBundleDef> OpBundles = None)
: IRBuilderBase(IP->getContext(), this->Folder, this->Inserter,
FPMathTag, OpBundles) {
SetInsertPoint(IP);
}
IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, FolderTy Folder,
MDNode *FPMathTag = nullptr,
ArrayRef<OperandBundleDef> OpBundles = None)
: IRBuilderBase(TheBB->getContext(), this->Folder, this->Inserter,
FPMathTag, OpBundles), Folder(Folder) {
SetInsertPoint(TheBB, IP);
}
IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP,
MDNode *FPMathTag = nullptr,
ArrayRef<OperandBundleDef> OpBundles = None)
: IRBuilderBase(TheBB->getContext(), this->Folder, this->Inserter,
FPMathTag, OpBundles) {
SetInsertPoint(TheBB, IP);
}
InserterTy &getInserter() { return Inserter; }
};
// Create wrappers for C Binding types (see CBindingWrapping.h).
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(IRBuilder<>, LLVMBuilderRef)

View File

@ -0,0 +1,139 @@
//===- IRBuilderFolder.h - Const folder interface for IRBuilder -*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines for constant folding interface used by IRBuilder.
// It is implemented by ConstantFolder (default), TargetFolder and NoFoler.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_IR_IRBUILDERFOLDER_H
#define LLVM_IR_IRBUILDERFOLDER_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
namespace llvm {
/// IRBuilderFolder - Interface for constant folding in IRBuilder.
class IRBuilderFolder {
public:
//===--------------------------------------------------------------------===//
// Binary Operators
//===--------------------------------------------------------------------===//
virtual Value *CreateAdd(Constant *LHS, Constant *RHS,
bool HasNUW = false, bool HasNSW = false) const = 0;
virtual Value *CreateFAdd(Constant *LHS, Constant *RHS) const = 0;
virtual Value *CreateSub(Constant *LHS, Constant *RHS,
bool HasNUW = false, bool HasNSW = false) const = 0;
virtual Value *CreateFSub(Constant *LHS, Constant *RHS) const = 0;
virtual Value *CreateMul(Constant *LHS, Constant *RHS,
bool HasNUW = false, bool HasNSW = false) const = 0;
virtual Value *CreateFMul(Constant *LHS, Constant *RHS) const = 0;
virtual Value *CreateUDiv(Constant *LHS, Constant *RHS,
bool isExact = false) const = 0;
virtual Value *CreateSDiv(Constant *LHS, Constant *RHS,
bool isExact = false) const = 0;
virtual Value *CreateFDiv(Constant *LHS, Constant *RHS) const = 0;
virtual Value *CreateURem(Constant *LHS, Constant *RHS) const = 0;
virtual Value *CreateSRem(Constant *LHS, Constant *RHS) const = 0;
virtual Value *CreateFRem(Constant *LHS, Constant *RHS) const = 0;
virtual Value *CreateShl(Constant *LHS, Constant *RHS,
bool HasNUW = false, bool HasNSW = false) const = 0;
virtual Value *CreateLShr(Constant *LHS, Constant *RHS,
bool isExact = false) const = 0;
virtual Value *CreateAShr(Constant *LHS, Constant *RHS,
bool isExact = false) const = 0;
virtual Value *CreateAnd(Constant *LHS, Constant *RHS) const = 0;
virtual Value *CreateOr(Constant *LHS, Constant *RHS) const = 0;
virtual Value *CreateXor(Constant *LHS, Constant *RHS) const = 0;
virtual Value *CreateBinOp(Instruction::BinaryOps Opc,
Constant *LHS, Constant *RHS) const = 0;
//===--------------------------------------------------------------------===//
// Unary Operators
//===--------------------------------------------------------------------===//
virtual Value *CreateNeg(Constant *C,
bool HasNUW = false, bool HasNSW = false) const = 0;
virtual Value *CreateFNeg(Constant *C) const = 0;
virtual Value *CreateNot(Constant *C) const = 0;
virtual Value *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const = 0;
//===--------------------------------------------------------------------===//
// Memory Instructions
//===--------------------------------------------------------------------===//
virtual Value *CreateGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Constant *> IdxList) const = 0;
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
virtual Value *CreateGetElementPtr(Type *Ty, Constant *C,
Constant *Idx) const = 0;
virtual Value *CreateGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Value *> IdxList) const = 0;
virtual Value *CreateInBoundsGetElementPtr(
Type *Ty, Constant *C, ArrayRef<Constant *> IdxList) const = 0;
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
virtual Value *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
Constant *Idx) const = 0;
virtual Value *CreateInBoundsGetElementPtr(
Type *Ty, Constant *C, ArrayRef<Value *> IdxList) const = 0;
//===--------------------------------------------------------------------===//
// Cast/Conversion Operators
//===--------------------------------------------------------------------===//
virtual Value *CreateCast(Instruction::CastOps Op, Constant *C,
Type *DestTy) const = 0;
virtual Value *CreatePointerCast(Constant *C, Type *DestTy) const = 0;
virtual Value *CreatePointerBitCastOrAddrSpaceCast(Constant *C,
Type *DestTy) const = 0;
virtual Value *CreateIntCast(Constant *C, Type *DestTy,
bool isSigned) const = 0;
virtual Value *CreateFPCast(Constant *C, Type *DestTy) const = 0;
virtual Value *CreateBitCast(Constant *C, Type *DestTy) const = 0;
virtual Value *CreateIntToPtr(Constant *C, Type *DestTy) const = 0;
virtual Value *CreatePtrToInt(Constant *C, Type *DestTy) const = 0;
virtual Value *CreateZExtOrBitCast(Constant *C, Type *DestTy) const = 0;
virtual Value *CreateSExtOrBitCast(Constant *C, Type *DestTy) const = 0;
virtual Value *CreateTruncOrBitCast(Constant *C, Type *DestTy) const = 0;
//===--------------------------------------------------------------------===//
// Compare Instructions
//===--------------------------------------------------------------------===//
virtual Value *CreateICmp(CmpInst::Predicate P, Constant *LHS,
Constant *RHS) const = 0;
virtual Value *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
Constant *RHS) const = 0;
//===--------------------------------------------------------------------===//
// Other Instructions
//===--------------------------------------------------------------------===//
virtual Value *CreateSelect(Constant *C, Constant *True,
Constant *False) const = 0;
virtual Value *CreateExtractElement(Constant *Vec, Constant *Idx) const = 0;
virtual Value *CreateInsertElement(Constant *Vec, Constant *NewElt,
Constant *Idx) const = 0;
virtual Value *CreateShuffleVector(Constant *V1, Constant *V2,
Constant *Mask) const = 0;
virtual Value *CreateExtractValue(Constant *Agg,
ArrayRef<unsigned> IdxList) const = 0;
virtual Value *CreateInsertValue(Constant *Agg, Constant *Val,
ArrayRef<unsigned> IdxList) const = 0;
};
} // end namespace llvm
#endif // LLVM_IR_IRBUILDERFOLDER_H

View File

@ -26,11 +26,14 @@
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IRBuilderFolder.h"
namespace llvm {
/// NoFolder - Create "constants" (actually, instructions) with no folding.
class NoFolder {
class NoFolder final : public IRBuilderFolder {
virtual void anchor();
public:
explicit NoFolder() = default;
@ -39,73 +42,76 @@ public:
//===--------------------------------------------------------------------===//
Instruction *CreateAdd(Constant *LHS, Constant *RHS,
bool HasNUW = false, bool HasNSW = false) const {
bool HasNUW = false,
bool HasNSW = false) const override {
BinaryOperator *BO = BinaryOperator::CreateAdd(LHS, RHS);
if (HasNUW) BO->setHasNoUnsignedWrap();
if (HasNSW) BO->setHasNoSignedWrap();
return BO;
}
Instruction *CreateFAdd(Constant *LHS, Constant *RHS) const {
Instruction *CreateFAdd(Constant *LHS, Constant *RHS) const override {
return BinaryOperator::CreateFAdd(LHS, RHS);
}
Instruction *CreateSub(Constant *LHS, Constant *RHS,
bool HasNUW = false, bool HasNSW = false) const {
bool HasNUW = false,
bool HasNSW = false) const override {
BinaryOperator *BO = BinaryOperator::CreateSub(LHS, RHS);
if (HasNUW) BO->setHasNoUnsignedWrap();
if (HasNSW) BO->setHasNoSignedWrap();
return BO;
}
Instruction *CreateFSub(Constant *LHS, Constant *RHS) const {
Instruction *CreateFSub(Constant *LHS, Constant *RHS) const override {
return BinaryOperator::CreateFSub(LHS, RHS);
}
Instruction *CreateMul(Constant *LHS, Constant *RHS,
bool HasNUW = false, bool HasNSW = false) const {
bool HasNUW = false,
bool HasNSW = false) const override {
BinaryOperator *BO = BinaryOperator::CreateMul(LHS, RHS);
if (HasNUW) BO->setHasNoUnsignedWrap();
if (HasNSW) BO->setHasNoSignedWrap();
return BO;
}
Instruction *CreateFMul(Constant *LHS, Constant *RHS) const {
Instruction *CreateFMul(Constant *LHS, Constant *RHS) const override {
return BinaryOperator::CreateFMul(LHS, RHS);
}
Instruction *CreateUDiv(Constant *LHS, Constant *RHS,
bool isExact = false) const {
bool isExact = false) const override {
if (!isExact)
return BinaryOperator::CreateUDiv(LHS, RHS);
return BinaryOperator::CreateExactUDiv(LHS, RHS);
}
Instruction *CreateSDiv(Constant *LHS, Constant *RHS,
bool isExact = false) const {
bool isExact = false) const override {
if (!isExact)
return BinaryOperator::CreateSDiv(LHS, RHS);
return BinaryOperator::CreateExactSDiv(LHS, RHS);
}
Instruction *CreateFDiv(Constant *LHS, Constant *RHS) const {
Instruction *CreateFDiv(Constant *LHS, Constant *RHS) const override {
return BinaryOperator::CreateFDiv(LHS, RHS);
}
Instruction *CreateURem(Constant *LHS, Constant *RHS) const {
Instruction *CreateURem(Constant *LHS, Constant *RHS) const override {
return BinaryOperator::CreateURem(LHS, RHS);
}
Instruction *CreateSRem(Constant *LHS, Constant *RHS) const {
Instruction *CreateSRem(Constant *LHS, Constant *RHS) const override {
return BinaryOperator::CreateSRem(LHS, RHS);
}
Instruction *CreateFRem(Constant *LHS, Constant *RHS) const {
Instruction *CreateFRem(Constant *LHS, Constant *RHS) const override {
return BinaryOperator::CreateFRem(LHS, RHS);
}
Instruction *CreateShl(Constant *LHS, Constant *RHS, bool HasNUW = false,
bool HasNSW = false) const {
bool HasNSW = false) const override {
BinaryOperator *BO = BinaryOperator::CreateShl(LHS, RHS);
if (HasNUW) BO->setHasNoUnsignedWrap();
if (HasNSW) BO->setHasNoSignedWrap();
@ -113,33 +119,33 @@ public:
}
Instruction *CreateLShr(Constant *LHS, Constant *RHS,
bool isExact = false) const {
bool isExact = false) const override {
if (!isExact)
return BinaryOperator::CreateLShr(LHS, RHS);
return BinaryOperator::CreateExactLShr(LHS, RHS);
}
Instruction *CreateAShr(Constant *LHS, Constant *RHS,
bool isExact = false) const {
bool isExact = false) const override {
if (!isExact)
return BinaryOperator::CreateAShr(LHS, RHS);
return BinaryOperator::CreateExactAShr(LHS, RHS);
}
Instruction *CreateAnd(Constant *LHS, Constant *RHS) const {
Instruction *CreateAnd(Constant *LHS, Constant *RHS) const override {
return BinaryOperator::CreateAnd(LHS, RHS);
}
Instruction *CreateOr(Constant *LHS, Constant *RHS) const {
Instruction *CreateOr(Constant *LHS, Constant *RHS) const override {
return BinaryOperator::CreateOr(LHS, RHS);
}
Instruction *CreateXor(Constant *LHS, Constant *RHS) const {
Instruction *CreateXor(Constant *LHS, Constant *RHS) const override {
return BinaryOperator::CreateXor(LHS, RHS);
}
Instruction *CreateBinOp(Instruction::BinaryOps Opc,
Constant *LHS, Constant *RHS) const {
Constant *LHS, Constant *RHS) const override {
return BinaryOperator::Create(Opc, LHS, RHS);
}
@ -148,22 +154,24 @@ public:
//===--------------------------------------------------------------------===//
Instruction *CreateNeg(Constant *C,
bool HasNUW = false, bool HasNSW = false) const {
bool HasNUW = false,
bool HasNSW = false) const override {
BinaryOperator *BO = BinaryOperator::CreateNeg(C);
if (HasNUW) BO->setHasNoUnsignedWrap();
if (HasNSW) BO->setHasNoSignedWrap();
return BO;
}
Instruction *CreateFNeg(Constant *C) const {
Instruction *CreateFNeg(Constant *C) const override {
return UnaryOperator::CreateFNeg(C);
}
Instruction *CreateNot(Constant *C) const {
Instruction *CreateNot(Constant *C) const override {
return BinaryOperator::CreateNot(C);
}
Instruction *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const {
Instruction *CreateUnOp(Instruction::UnaryOps Opc,
Constant *C) const override {
return UnaryOperator::Create(Opc, C);
}
@ -172,11 +180,12 @@ public:
//===--------------------------------------------------------------------===//
Constant *CreateGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Constant *> IdxList) const {
ArrayRef<Constant *> IdxList) const override {
return ConstantExpr::getGetElementPtr(Ty, C, IdxList);
}
Constant *CreateGetElementPtr(Type *Ty, Constant *C, Constant *Idx) const {
Constant *CreateGetElementPtr(Type *Ty, Constant *C,
Constant *Idx) const override {
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
@ -184,25 +193,25 @@ public:
}
Instruction *CreateGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Value *> IdxList) const {
ArrayRef<Value *> IdxList) const override {
return GetElementPtrInst::Create(Ty, C, IdxList);
}
Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Constant *> IdxList) const {
Constant *CreateInBoundsGetElementPtr(
Type *Ty, Constant *C, ArrayRef<Constant *> IdxList) const override {
return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList);
}
Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
Constant *Idx) const {
Constant *Idx) const override {
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
return ConstantExpr::getInBoundsGetElementPtr(Ty, C, Idx);
}
Instruction *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Value *> IdxList) const {
Instruction *CreateInBoundsGetElementPtr(
Type *Ty, Constant *C, ArrayRef<Value *> IdxList) const override {
return GetElementPtrInst::CreateInBounds(Ty, C, IdxList);
}
@ -211,49 +220,49 @@ public:
//===--------------------------------------------------------------------===//
Instruction *CreateCast(Instruction::CastOps Op, Constant *C,
Type *DestTy) const {
Type *DestTy) const override {
return CastInst::Create(Op, C, DestTy);
}
Instruction *CreatePointerCast(Constant *C, Type *DestTy) const {
Instruction *CreatePointerCast(Constant *C, Type *DestTy) const override {
return CastInst::CreatePointerCast(C, DestTy);
}
Instruction *CreatePointerBitCastOrAddrSpaceCast(
Constant *C, Type *DestTy) const {
Constant *C, Type *DestTy) const override {
return CastInst::CreatePointerBitCastOrAddrSpaceCast(C, DestTy);
}
Instruction *CreateIntCast(Constant *C, Type *DestTy,
bool isSigned) const {
bool isSigned) const override {
return CastInst::CreateIntegerCast(C, DestTy, isSigned);
}
Instruction *CreateFPCast(Constant *C, Type *DestTy) const {
Instruction *CreateFPCast(Constant *C, Type *DestTy) const override {
return CastInst::CreateFPCast(C, DestTy);
}
Instruction *CreateBitCast(Constant *C, Type *DestTy) const {
Instruction *CreateBitCast(Constant *C, Type *DestTy) const override {
return CreateCast(Instruction::BitCast, C, DestTy);
}
Instruction *CreateIntToPtr(Constant *C, Type *DestTy) const {
Instruction *CreateIntToPtr(Constant *C, Type *DestTy) const override {
return CreateCast(Instruction::IntToPtr, C, DestTy);
}
Instruction *CreatePtrToInt(Constant *C, Type *DestTy) const {
Instruction *CreatePtrToInt(Constant *C, Type *DestTy) const override {
return CreateCast(Instruction::PtrToInt, C, DestTy);
}
Instruction *CreateZExtOrBitCast(Constant *C, Type *DestTy) const {
Instruction *CreateZExtOrBitCast(Constant *C, Type *DestTy) const override {
return CastInst::CreateZExtOrBitCast(C, DestTy);
}
Instruction *CreateSExtOrBitCast(Constant *C, Type *DestTy) const {
Instruction *CreateSExtOrBitCast(Constant *C, Type *DestTy) const override {
return CastInst::CreateSExtOrBitCast(C, DestTy);
}
Instruction *CreateTruncOrBitCast(Constant *C, Type *DestTy) const {
Instruction *CreateTruncOrBitCast(Constant *C, Type *DestTy) const override {
return CastInst::CreateTruncOrBitCast(C, DestTy);
}
@ -262,12 +271,12 @@ public:
//===--------------------------------------------------------------------===//
Instruction *CreateICmp(CmpInst::Predicate P,
Constant *LHS, Constant *RHS) const {
Constant *LHS, Constant *RHS) const override {
return new ICmpInst(P, LHS, RHS);
}
Instruction *CreateFCmp(CmpInst::Predicate P,
Constant *LHS, Constant *RHS) const {
Constant *LHS, Constant *RHS) const override {
return new FCmpInst(P, LHS, RHS);
}
@ -276,31 +285,32 @@ public:
//===--------------------------------------------------------------------===//
Instruction *CreateSelect(Constant *C,
Constant *True, Constant *False) const {
Constant *True, Constant *False) const override {
return SelectInst::Create(C, True, False);
}
Instruction *CreateExtractElement(Constant *Vec, Constant *Idx) const {
Instruction *CreateExtractElement(Constant *Vec,
Constant *Idx) const override {
return ExtractElementInst::Create(Vec, Idx);
}
Instruction *CreateInsertElement(Constant *Vec, Constant *NewElt,
Constant *Idx) const {
Constant *Idx) const override {
return InsertElementInst::Create(Vec, NewElt, Idx);
}
Instruction *CreateShuffleVector(Constant *V1, Constant *V2,
Constant *Mask) const {
Constant *Mask) const override {
return new ShuffleVectorInst(V1, V2, Mask);
}
Instruction *CreateExtractValue(Constant *Agg,
ArrayRef<unsigned> IdxList) const {
ArrayRef<unsigned> IdxList) const override {
return ExtractValueInst::Create(Agg, IdxList);
}
Instruction *CreateInsertValue(Constant *Agg, Constant *Val,
ArrayRef<unsigned> IdxList) const {
ArrayRef<unsigned> IdxList) const override {
return InsertValueInst::Create(Agg, Val, IdxList);
}
};

View File

@ -23,6 +23,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/TargetFolder.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Analysis/VectorUtils.h"
@ -2660,3 +2661,5 @@ bool llvm::isMathLibCallNoop(const CallBase *Call,
return false;
}
void TargetFolder::anchor() {}

View File

@ -24,6 +24,7 @@
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/NoFolder.h"
#include "llvm/IR/Statepoint.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
@ -784,3 +785,8 @@ CallInst *IRBuilderBase::CreateIntrinsic(Intrinsic::ID ID,
Function *Fn = Intrinsic::getDeclaration(M, ID, Types);
return createCallHelper(Fn, Args, this, Name, FMFSource);
}
void IRBuilderDefaultInserter::anchor() {}
void IRBuilderCallbackInserter::anchor() {}
void ConstantFolder::anchor() {}
void NoFolder::anchor() {}

View File

@ -139,9 +139,8 @@ class IRBuilderPrefixedInserter : public IRBuilderDefaultInserter {
public:
void SetNamePrefix(const Twine &P) { Prefix = P.str(); }
protected:
void InsertHelper(Instruction *I, const Twine &Name, BasicBlock *BB,
BasicBlock::iterator InsertPt) const {
BasicBlock::iterator InsertPt) const override {
IRBuilderDefaultInserter::InsertHelper(I, getNameWithPrefix(Name), BB,
InsertPt);
}
@ -2368,7 +2367,8 @@ public:
Instruction *OldUserI = cast<Instruction>(OldUse->getUser());
IRB.SetInsertPoint(OldUserI);
IRB.SetCurrentDebugLocation(OldUserI->getDebugLoc());
IRB.SetNamePrefix(Twine(NewAI.getName()) + "." + Twine(BeginOffset) + ".");
IRB.getInserter().SetNamePrefix(
Twine(NewAI.getName()) + "." + Twine(BeginOffset) + ".");
CanSROA &= visit(cast<Instruction>(OldUse->getUser()));
if (VecTy || IntTy)