Skip to content

Commit f73d24b

Browse files
committed
[SandboxIR] Implement SandboxIR Type
This patch implements sandboxir::Type, a thin wrapper of llvm::Type. This is designed very similarly to sandbox::Value. Context owns all sandboxir::Type objects and maintains a map between llvm::Type and sandboxir::Type. There are a couple of reasons for migrating from llvm::Type to sandboxir::Type: - Creating an llvm::Type from within SandboxIR-only code doesn't work well because it requires you to pass llvm::Context to functions like llvm::Type::getInt32Ty(C), but you wouldn't normally have access to llvm::Context C. - Not being able to get the sandboxir::Context from llvm::Type results in awkward sandboir APIs with additional sandboxir::Context arguments. - llvm::Type::getContext() can basically give you access to the whole LLVM IR, which we should try to avoid.
1 parent 1bde8e0 commit f73d24b

File tree

9 files changed

+754
-101
lines changed

9 files changed

+754
-101
lines changed

llvm/include/llvm/SandboxIR/SandboxIR.h

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
#include "llvm/IR/User.h"
101101
#include "llvm/IR/Value.h"
102102
#include "llvm/SandboxIR/Tracker.h"
103+
#include "llvm/SandboxIR/Type.h"
103104
#include "llvm/SandboxIR/Use.h"
104105
#include "llvm/Support/raw_ostream.h"
105106
#include <iterator>
@@ -382,7 +383,7 @@ class Value {
382383
return Cnt == Num;
383384
}
384385

385-
Type *getType() const { return Val->getType(); }
386+
Type *getType() const;
386387

387388
Context &getContext() const { return Ctx; }
388389

@@ -570,8 +571,7 @@ class ConstantInt : public Constant {
570571
public:
571572
/// If Ty is a vector type, return a Constant with a splat of the given
572573
/// value. Otherwise return a ConstantInt for the given value.
573-
static ConstantInt *get(Type *Ty, uint64_t V, Context &Ctx,
574-
bool IsSigned = false);
574+
static ConstantInt *get(Type *Ty, uint64_t V, bool IsSigned = false);
575575

576576
// TODO: Implement missing functions.
577577

@@ -1019,10 +1019,7 @@ class ExtractElementInst final
10191019
Value *getIndexOperand() { return getOperand(1); }
10201020
const Value *getVectorOperand() const { return getOperand(0); }
10211021
const Value *getIndexOperand() const { return getOperand(1); }
1022-
1023-
VectorType *getVectorOperandType() const {
1024-
return cast<VectorType>(getVectorOperand()->getType());
1025-
}
1022+
VectorType *getVectorOperandType() const;
10261023
};
10271024

10281025
class ShuffleVectorInst final
@@ -1067,9 +1064,7 @@ class ShuffleVectorInst final
10671064
}
10681065

10691066
/// Overload to return most specific vector type.
1070-
VectorType *getType() const {
1071-
return cast<llvm::ShuffleVectorInst>(Val)->getType();
1072-
}
1067+
VectorType *getType() const;
10731068

10741069
/// Return the shuffle mask value of this instruction for the given element
10751070
/// index. Return PoisonMaskElem if the element is undef.
@@ -1095,7 +1090,7 @@ class ShuffleVectorInst final
10951090
Constant *getShuffleMaskForBitcode() const;
10961091

10971092
static Constant *convertShuffleMaskForBitcode(ArrayRef<int> Mask,
1098-
Type *ResultTy, Context &Ctx);
1093+
Type *ResultTy);
10991094

11001095
void setShuffleMask(ArrayRef<int> Mask);
11011096

@@ -1779,9 +1774,7 @@ class CallBase : public SingleLLVMInstructionImpl<llvm::CallBase> {
17791774
Opc == Instruction::ClassID::CallBr;
17801775
}
17811776

1782-
FunctionType *getFunctionType() const {
1783-
return cast<llvm::CallBase>(Val)->getFunctionType();
1784-
}
1777+
FunctionType *getFunctionType() const;
17851778

17861779
op_iterator data_operands_begin() { return op_begin(); }
17871780
const_op_iterator data_operands_begin() const {
@@ -2197,12 +2190,8 @@ class GetElementPtrInst final
21972190
return From->getSubclassID() == ClassID::GetElementPtr;
21982191
}
21992192

2200-
Type *getSourceElementType() const {
2201-
return cast<llvm::GetElementPtrInst>(Val)->getSourceElementType();
2202-
}
2203-
Type *getResultElementType() const {
2204-
return cast<llvm::GetElementPtrInst>(Val)->getResultElementType();
2205-
}
2193+
Type *getSourceElementType() const;
2194+
Type *getResultElementType() const;
22062195
unsigned getAddressSpace() const {
22072196
return cast<llvm::GetElementPtrInst>(Val)->getAddressSpace();
22082197
}
@@ -2226,9 +2215,7 @@ class GetElementPtrInst final
22262215
static unsigned getPointerOperandIndex() {
22272216
return llvm::GetElementPtrInst::getPointerOperandIndex();
22282217
}
2229-
Type *getPointerOperandType() const {
2230-
return cast<llvm::GetElementPtrInst>(Val)->getPointerOperandType();
2231-
}
2218+
Type *getPointerOperandType() const;
22322219
unsigned getPointerAddressSpace() const {
22332220
return cast<llvm::GetElementPtrInst>(Val)->getPointerAddressSpace();
22342221
}
@@ -2775,9 +2762,7 @@ class AllocaInst final : public UnaryInstruction {
27752762
return const_cast<AllocaInst *>(this)->getArraySize();
27762763
}
27772764
/// Overload to return most specific pointer type.
2778-
PointerType *getType() const {
2779-
return cast<llvm::AllocaInst>(Val)->getType();
2780-
}
2765+
PointerType *getType() const;
27812766
/// Return the address space for the allocation.
27822767
unsigned getAddressSpace() const {
27832768
return cast<llvm::AllocaInst>(Val)->getAddressSpace();
@@ -2793,9 +2778,7 @@ class AllocaInst final : public UnaryInstruction {
27932778
return cast<llvm::AllocaInst>(Val)->getAllocationSizeInBits(DL);
27942779
}
27952780
/// Return the type that is being allocated by the instruction.
2796-
Type *getAllocatedType() const {
2797-
return cast<llvm::AllocaInst>(Val)->getAllocatedType();
2798-
}
2781+
Type *getAllocatedType() const;
27992782
/// for use only in special circumstances that need to generically
28002783
/// transform a whole instruction (eg: IR linking and vectorization).
28012784
void setAllocatedType(Type *Ty);
@@ -2877,8 +2860,8 @@ class CastInst : public UnaryInstruction {
28772860
const Twine &Name = "");
28782861
/// For isa/dyn_cast.
28792862
static bool classof(const Value *From);
2880-
Type *getSrcTy() const { return cast<llvm::CastInst>(Val)->getSrcTy(); }
2881-
Type *getDestTy() const { return cast<llvm::CastInst>(Val)->getDestTy(); }
2863+
Type *getSrcTy() const;
2864+
Type *getDestTy() const;
28822865
};
28832866

28842867
/// Instruction that can have a nneg flag (zext/uitofp).
@@ -3058,13 +3041,25 @@ class OpaqueInst : public SingleLLVMInstructionImpl<llvm::Instruction> {
30583041
class Context {
30593042
protected:
30603043
LLVMContext &LLVMCtx;
3044+
friend class Type; // For LLVMCtx.
3045+
friend class PointerType; // For LLVMCtx.
30613046
Tracker IRTracker;
30623047

30633048
/// Maps LLVM Value to the corresponding sandboxir::Value. Owns all
30643049
/// SandboxIR objects.
30653050
DenseMap<llvm::Value *, std::unique_ptr<sandboxir::Value>>
30663051
LLVMValueToValueMap;
30673052

3053+
/// Type has a protected destructor to prohibit the user from managing the
3054+
/// lifetime of the Type objects. Context is friend of Type, and this custom
3055+
/// deleter can destroy Type.
3056+
struct TypeDeleter {
3057+
void operator()(Type *Ty) { delete Ty; }
3058+
};
3059+
/// Maps LLVM Type to the corresonding sandboxir::Type. Owns all Sandbox IR
3060+
/// Type objects.
3061+
DenseMap<llvm::Type *, std::unique_ptr<Type, TypeDeleter>> LLVMTypeToTypeMap;
3062+
30683063
/// Remove \p V from the maps and returns the unique_ptr.
30693064
std::unique_ptr<Value> detachLLVMValue(llvm::Value *V);
30703065
/// Remove \p SBV from all SandboxIR maps and stop owning it. This effectively
@@ -3099,7 +3094,6 @@ class Context {
30993094
/// Create a sandboxir::BasicBlock for an existing LLVM IR \p BB. This will
31003095
/// also create all contents of the block.
31013096
BasicBlock *createBasicBlock(llvm::BasicBlock *BB);
3102-
31033097
friend class BasicBlock; // For getOrCreateValue().
31043098

31053099
IRBuilder<ConstantFolder> LLVMIRBuilder;
@@ -3187,6 +3181,15 @@ class Context {
31873181
const sandboxir::Value *getValue(const llvm::Value *V) const {
31883182
return getValue(const_cast<llvm::Value *>(V));
31893183
}
3184+
3185+
Type *getType(llvm::Type *LLVMTy) {
3186+
auto Pair = LLVMTypeToTypeMap.insert({LLVMTy, nullptr});
3187+
auto It = Pair.first;
3188+
if (Pair.second)
3189+
It->second = std::unique_ptr<Type, TypeDeleter>(new Type(LLVMTy, *this));
3190+
return It->second.get();
3191+
}
3192+
31903193
/// Create a sandboxir::Function for an existing LLVM IR \p F, including all
31913194
/// blocks and instructions.
31923195
/// This is the main API function for creating Sandbox IR.
@@ -3233,9 +3236,7 @@ class Function : public Constant {
32333236
LLVMBBToBB BBGetter(Ctx);
32343237
return iterator(cast<llvm::Function>(Val)->end(), BBGetter);
32353238
}
3236-
FunctionType *getFunctionType() const {
3237-
return cast<llvm::Function>(Val)->getFunctionType();
3238-
}
3239+
FunctionType *getFunctionType() const;
32393240

32403241
#ifndef NDEBUG
32413242
void verify() const final {

0 commit comments

Comments
 (0)