CGBuilder.h revision 296417
119370Spst//===-- CGBuilder.h - Choose IRBuilder implementation  ----------*- C++ -*-===//
298944Sobrien//
398944Sobrien//                     The LLVM Compiler Infrastructure
498944Sobrien//
519370Spst// This file is distributed under the University of Illinois Open Source
619370Spst// License. See LICENSE.TXT for details.
719370Spst//
819370Spst//===----------------------------------------------------------------------===//
919370Spst
1019370Spst#ifndef LLVM_CLANG_LIB_CODEGEN_CGBUILDER_H
1119370Spst#define LLVM_CLANG_LIB_CODEGEN_CGBUILDER_H
1219370Spst
1319370Spst#include "llvm/IR/IRBuilder.h"
1419370Spst#include "Address.h"
1519370Spst#include "CodeGenTypeCache.h"
1619370Spst
1719370Spstnamespace clang {
1819370Spstnamespace CodeGen {
1919370Spst
2019370Spstclass CodeGenFunction;
2119370Spst
2219370Spst/// \brief This is an IRBuilder insertion helper that forwards to
2319370Spst/// CodeGenFunction::InsertHelper, which adds necessary metadata to
2419370Spst/// instructions.
2519370Spsttemplate <bool PreserveNames>
2619370Spstclass CGBuilderInserter
2719370Spst    : protected llvm::IRBuilderDefaultInserter<PreserveNames> {
2819370Spstpublic:
2919370Spst  CGBuilderInserter() = default;
3019370Spst  explicit CGBuilderInserter(CodeGenFunction *CGF) : CGF(CGF) {}
3119370Spst
3219370Spstprotected:
3319370Spst  /// \brief This forwards to CodeGenFunction::InsertHelper.
3419370Spst  void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name,
3519370Spst                    llvm::BasicBlock *BB,
3619370Spst                    llvm::BasicBlock::iterator InsertPt) const;
3719370Spstprivate:
3819370Spst  CodeGenFunction *CGF = nullptr;
3919370Spst};
4019370Spst
4119370Spst// Don't preserve names on values in an optimized build.
4219370Spst#ifdef NDEBUG
4319370Spst#define PreserveNames false
4419370Spst#else
4519370Spst#define PreserveNames true
4619370Spst#endif
4719370Spst
4819370Spsttypedef CGBuilderInserter<PreserveNames> CGBuilderInserterTy;
4919370Spst
5019370Spsttypedef llvm::IRBuilder<PreserveNames, llvm::ConstantFolder,
5119370Spst                        CGBuilderInserterTy> CGBuilderBaseTy;
5219370Spst
5319370Spstclass CGBuilderTy : public CGBuilderBaseTy {
5419370Spst  /// Storing a reference to the type cache here makes it a lot easier
5519370Spst  /// to build natural-feeling, target-specific IR.
56130803Smarcel  const CodeGenTypeCache &TypeCache;
5798944Sobrienpublic:
5819370Spst  CGBuilderTy(const CodeGenTypeCache &TypeCache, llvm::LLVMContext &C)
5919370Spst    : CGBuilderBaseTy(C), TypeCache(TypeCache) {}
6019370Spst  CGBuilderTy(const CodeGenTypeCache &TypeCache,
6119370Spst              llvm::LLVMContext &C, const llvm::ConstantFolder &F,
6219370Spst              const CGBuilderInserterTy &Inserter)
6319370Spst    : CGBuilderBaseTy(C, F, Inserter), TypeCache(TypeCache) {}
6419370Spst  CGBuilderTy(const CodeGenTypeCache &TypeCache, llvm::Instruction *I)
6519370Spst    : CGBuilderBaseTy(I), TypeCache(TypeCache) {}
6619370Spst  CGBuilderTy(const CodeGenTypeCache &TypeCache, llvm::BasicBlock *BB)
6719370Spst    : CGBuilderBaseTy(BB), TypeCache(TypeCache) {}
6819370Spst
6919370Spst  llvm::ConstantInt *getSize(CharUnits N) {
7019370Spst    return llvm::ConstantInt::get(TypeCache.SizeTy, N.getQuantity());
7119370Spst  }
7219370Spst  llvm::ConstantInt *getSize(uint64_t N) {
7319370Spst    return llvm::ConstantInt::get(TypeCache.SizeTy, N);
7419370Spst  }
7519370Spst
7619370Spst  // Note that we intentionally hide the CreateLoad APIs that don't
7719370Spst  // take an alignment.
7819370Spst  llvm::LoadInst *CreateLoad(Address Addr, const llvm::Twine &Name = "") {
7919370Spst    return CreateAlignedLoad(Addr.getPointer(),
8019370Spst                             Addr.getAlignment().getQuantity(),
8119370Spst                             Name);
8219370Spst  }
8319370Spst  llvm::LoadInst *CreateLoad(Address Addr, const char *Name) {
8419370Spst    // This overload is required to prevent string literals from
8519370Spst    // ending up in the IsVolatile overload.
8619370Spst    return CreateAlignedLoad(Addr.getPointer(),
8719370Spst                             Addr.getAlignment().getQuantity(),
8819370Spst                             Name);
8919370Spst  }
9019370Spst  llvm::LoadInst *CreateLoad(Address Addr, bool IsVolatile,
9119370Spst                             const llvm::Twine &Name = "") {
9219370Spst    return CreateAlignedLoad(Addr.getPointer(),
9319370Spst                             Addr.getAlignment().getQuantity(),
9419370Spst                             IsVolatile,
95130803Smarcel                             Name);
96130803Smarcel  }
9719370Spst
9819370Spst  using CGBuilderBaseTy::CreateAlignedLoad;
9919370Spst  llvm::LoadInst *CreateAlignedLoad(llvm::Value *Addr, CharUnits Align,
10019370Spst                                    const llvm::Twine &Name = "") {
10119370Spst    return CreateAlignedLoad(Addr, Align.getQuantity(), Name);
10219370Spst  }
10319370Spst  llvm::LoadInst *CreateAlignedLoad(llvm::Value *Addr, CharUnits Align,
10419370Spst                                    const char *Name) {
10519370Spst    return CreateAlignedLoad(Addr, Align.getQuantity(), Name);
10619370Spst  }
10719370Spst  llvm::LoadInst *CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr,
108130803Smarcel                                    CharUnits Align,
10919370Spst                                    const llvm::Twine &Name = "") {
11019370Spst    assert(Addr->getType()->getPointerElementType() == Ty);
111130803Smarcel    return CreateAlignedLoad(Addr, Align.getQuantity(), Name);
112130803Smarcel  }
11398944Sobrien  llvm::LoadInst *CreateAlignedLoad(llvm::Value *Addr, CharUnits Align,
11419370Spst                                    bool IsVolatile,
11598944Sobrien                                    const llvm::Twine &Name = "") {
11619370Spst    return CreateAlignedLoad(Addr, Align.getQuantity(), IsVolatile, Name);
11798944Sobrien  }
11819370Spst
11998944Sobrien  // Note that we intentionally hide the CreateStore APIs that don't
12046283Sdfr  // take an alignment.
12198944Sobrien  llvm::StoreInst *CreateStore(llvm::Value *Val, Address Addr,
12246283Sdfr                               bool IsVolatile = false) {
12319370Spst    return CreateAlignedStore(Val, Addr.getPointer(),
12419370Spst                              Addr.getAlignment().getQuantity(), IsVolatile);
12519370Spst  }
12619370Spst
12719370Spst  using CGBuilderBaseTy::CreateAlignedStore;
12819370Spst  llvm::StoreInst *CreateAlignedStore(llvm::Value *Val, llvm::Value *Addr,
12919370Spst                                      CharUnits Align, bool IsVolatile = false) {
13019370Spst    return CreateAlignedStore(Val, Addr, Align.getQuantity(), IsVolatile);
13119370Spst  }
13219370Spst
13319370Spst  // FIXME: these "default-aligned" APIs should be removed,
13419370Spst  // but I don't feel like fixing all the builtin code right now.
13519370Spst  llvm::LoadInst *CreateDefaultAlignedLoad(llvm::Value *Addr,
13619370Spst                                           const llvm::Twine &Name = "") {
13719370Spst    return CGBuilderBaseTy::CreateLoad(Addr, false, Name);
13819370Spst  }
13919370Spst  llvm::LoadInst *CreateDefaultAlignedLoad(llvm::Value *Addr,
14019370Spst                                           const char *Name) {
14119370Spst    return CGBuilderBaseTy::CreateLoad(Addr, false, Name);
14219370Spst  }
14319370Spst  llvm::LoadInst *CreateDefaultAlignedLoad(llvm::Value *Addr, bool IsVolatile,
14419370Spst                                           const llvm::Twine &Name = "") {
14519370Spst    return CGBuilderBaseTy::CreateLoad(Addr, IsVolatile, Name);
14619370Spst  }
14719370Spst
14819370Spst  llvm::StoreInst *CreateDefaultAlignedStore(llvm::Value *Val,
14919370Spst                                             llvm::Value *Addr,
15019370Spst                                             bool IsVolatile = false) {
15119370Spst    return CGBuilderBaseTy::CreateStore(Val, Addr, IsVolatile);
15219370Spst  }
15398944Sobrien
15419370Spst  /// Emit a load from an i1 flag variable.
15519370Spst  llvm::LoadInst *CreateFlagLoad(llvm::Value *Addr,
15619370Spst                                 const llvm::Twine &Name = "") {
15719370Spst    assert(Addr->getType()->getPointerElementType() == getInt1Ty());
15819370Spst    return CreateAlignedLoad(getInt1Ty(), Addr, CharUnits::One(), Name);
15919370Spst  }
16019370Spst
16119370Spst  /// Emit a store to an i1 flag variable.
16219370Spst  llvm::StoreInst *CreateFlagStore(bool Value, llvm::Value *Addr) {
16319370Spst    assert(Addr->getType()->getPointerElementType() == getInt1Ty());
16419370Spst    return CreateAlignedStore(getInt1(Value), Addr, CharUnits::One());
16519370Spst  }
16619370Spst
16719370Spst  using CGBuilderBaseTy::CreateBitCast;
16819370Spst  Address CreateBitCast(Address Addr, llvm::Type *Ty,
16919370Spst                        const llvm::Twine &Name = "") {
17019370Spst    return Address(CreateBitCast(Addr.getPointer(), Ty, Name),
17119370Spst                   Addr.getAlignment());
17219370Spst  }
17319370Spst
17419370Spst  /// Cast the element type of the given address to a different type,
17519370Spst  /// preserving information like the alignment and address space.
17619370Spst  Address CreateElementBitCast(Address Addr, llvm::Type *Ty,
17719370Spst                               const llvm::Twine &Name = "") {
17819370Spst    auto PtrTy = Ty->getPointerTo(Addr.getAddressSpace());
17919370Spst    return CreateBitCast(Addr, PtrTy, Name);
18019370Spst  }
18119370Spst
18219370Spst  using CGBuilderBaseTy::CreatePointerBitCastOrAddrSpaceCast;
18319370Spst  Address CreatePointerBitCastOrAddrSpaceCast(Address Addr, llvm::Type *Ty,
18419370Spst                                              const llvm::Twine &Name = "") {
18519370Spst    llvm::Value *Ptr =
18619370Spst      CreatePointerBitCastOrAddrSpaceCast(Addr.getPointer(), Ty, Name);
18719370Spst    return Address(Ptr, Addr.getAlignment());
18819370Spst  }
18919370Spst
19019370Spst  using CGBuilderBaseTy::CreateStructGEP;
19119370Spst  Address CreateStructGEP(Address Addr, unsigned Index, CharUnits Offset,
19219370Spst                          const llvm::Twine &Name = "") {
19319370Spst    return Address(CreateStructGEP(Addr.getElementType(),
19419370Spst                                   Addr.getPointer(), Index, Name),
19519370Spst                   Addr.getAlignment().alignmentAtOffset(Offset));
19619370Spst  }
19719370Spst
19819370Spst  /// Given
19919370Spst  ///   %addr = [n x T]* ...
20019370Spst  /// produce
20119370Spst  ///   %name = getelementptr inbounds %addr, i64 0, i64 index
20219370Spst  /// where i64 is actually the target word size.
20319370Spst  ///
20419370Spst  /// This API assumes that drilling into an array like this is always
20519370Spst  /// an inbounds operation.
20619370Spst  ///
20719370Spst  /// \param EltSize - the size of the type T in bytes
20819370Spst  Address CreateConstArrayGEP(Address Addr, uint64_t Index, CharUnits EltSize,
20919370Spst                              const llvm::Twine &Name = "") {
21019370Spst    return Address(CreateInBoundsGEP(Addr.getPointer(),
21119370Spst                                     {getSize(CharUnits::Zero()),
21219370Spst                                      getSize(Index)},
21319370Spst                                     Name),
21419370Spst                   Addr.getAlignment().alignmentAtOffset(Index * EltSize));
21519370Spst  }
21619370Spst
21719370Spst  /// Given
21819370Spst  ///   %addr = T* ...
21919370Spst  /// produce
22019370Spst  ///   %name = getelementptr inbounds %addr, i64 index
22119370Spst  /// where i64 is actually the target word size.
22219370Spst  ///
22319370Spst  /// \param EltSize - the size of the type T in bytes
22419370Spst  Address CreateConstInBoundsGEP(Address Addr, uint64_t Index,
22519370Spst                                 CharUnits EltSize,
22619370Spst                                 const llvm::Twine &Name = "") {
22719370Spst    return Address(CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(),
22819370Spst                                     getSize(Index), Name),
22919370Spst                   Addr.getAlignment().alignmentAtOffset(Index * EltSize));
23019370Spst  }
23119370Spst
23219370Spst  /// Given
23319370Spst  ///   %addr = T* ...
23419370Spst  /// produce
23519370Spst  ///   %name = getelementptr inbounds %addr, i64 index
23619370Spst  /// where i64 is actually the target word size.
23719370Spst  ///
23819370Spst  /// \param EltSize - the size of the type T in bytes
23919370Spst  Address CreateConstGEP(Address Addr, uint64_t Index, CharUnits EltSize,
24019370Spst                         const llvm::Twine &Name = "") {
24119370Spst    return Address(CreateGEP(Addr.getElementType(), Addr.getPointer(),
24219370Spst                             getSize(Index), Name),
24319370Spst                   Addr.getAlignment().alignmentAtOffset(Index * EltSize));
24419370Spst  }
245130803Smarcel
24619370Spst  /// Given a pointer to i8, adjust it by a given constant offset.
24719370Spst  Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset,
24819370Spst                                     const llvm::Twine &Name = "") {
249130803Smarcel    assert(Addr.getElementType() == TypeCache.Int8Ty);
25019370Spst    return Address(CreateInBoundsGEP(Addr.getPointer(), getSize(Offset), Name),
25119370Spst                   Addr.getAlignment().alignmentAtOffset(Offset));
25219370Spst  }
25319370Spst  Address CreateConstByteGEP(Address Addr, CharUnits Offset,
25419370Spst                             const llvm::Twine &Name = "") {
25519370Spst    assert(Addr.getElementType() == TypeCache.Int8Ty);
25619370Spst    return Address(CreateGEP(Addr.getPointer(), getSize(Offset), Name),
25719370Spst                   Addr.getAlignment().alignmentAtOffset(Offset));
25819370Spst  }
25919370Spst
26019370Spst  llvm::Value *CreateConstInBoundsByteGEP(llvm::Value *Ptr, CharUnits Offset,
26119370Spst                                          const llvm::Twine &Name = "") {
26219370Spst    assert(Ptr->getType()->getPointerElementType() == TypeCache.Int8Ty);
26319370Spst    return CreateInBoundsGEP(Ptr, getSize(Offset), Name);
26419370Spst  }
26519370Spst  llvm::Value *CreateConstByteGEP(llvm::Value *Ptr, CharUnits Offset,
26619370Spst                                  const llvm::Twine &Name = "") {
26719370Spst    assert(Ptr->getType()->getPointerElementType() == TypeCache.Int8Ty);
26819370Spst    return CreateGEP(Ptr, getSize(Offset), Name);
26919370Spst  }
27019370Spst
27119370Spst  using CGBuilderBaseTy::CreateMemCpy;
27219370Spst  llvm::CallInst *CreateMemCpy(Address Dest, Address Src, llvm::Value *Size,
27319370Spst                               bool IsVolatile = false) {
27419370Spst    auto Align = std::min(Dest.getAlignment(), Src.getAlignment());
27519370Spst    return CreateMemCpy(Dest.getPointer(), Src.getPointer(), Size,
27619370Spst                        Align.getQuantity(), IsVolatile);
27719370Spst  }
27819370Spst  llvm::CallInst *CreateMemCpy(Address Dest, Address Src, uint64_t Size,
27919370Spst                               bool IsVolatile = false) {
28019370Spst    auto Align = std::min(Dest.getAlignment(), Src.getAlignment());
28119370Spst    return CreateMemCpy(Dest.getPointer(), Src.getPointer(), Size,
28219370Spst                        Align.getQuantity(), IsVolatile);
28319370Spst  }
28419370Spst
28519370Spst  using CGBuilderBaseTy::CreateMemMove;
28619370Spst  llvm::CallInst *CreateMemMove(Address Dest, Address Src, llvm::Value *Size,
28719370Spst                                bool IsVolatile = false) {
28819370Spst    auto Align = std::min(Dest.getAlignment(), Src.getAlignment());
289130803Smarcel    return CreateMemMove(Dest.getPointer(), Src.getPointer(), Size,
29019370Spst                         Align.getQuantity(), IsVolatile);
29119370Spst  }
29219370Spst
29319370Spst  using CGBuilderBaseTy::CreateMemSet;
29419370Spst  llvm::CallInst *CreateMemSet(Address Dest, llvm::Value *Value,
29519370Spst                               llvm::Value *Size, bool IsVolatile = false) {
29619370Spst    return CreateMemSet(Dest.getPointer(), Value, Size,
29719370Spst                        Dest.getAlignment().getQuantity(), IsVolatile);
29819370Spst  }
29919370Spst};
30019370Spst
30119370Spst#undef PreserveNames
30219370Spst
30319370Spst}  // end namespace CodeGen
30419370Spst}  // end namespace clang
30519370Spst
30619370Spst#endif
30719370Spst