Skip to content

Commit f9765a2

Browse files
authored
[SandboxIR] Implement GetElementPtrInst (llvm#101078)
This patch implements sandboxir::GetElementPtrInst which mirrors llvm::GetElementPtrInst.
1 parent 2c3eb8d commit f9765a2

File tree

4 files changed

+329
-20
lines changed

4 files changed

+329
-20
lines changed

llvm/include/llvm/SandboxIR/SandboxIR.h

Lines changed: 129 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ class CallBase;
9393
class CallInst;
9494
class InvokeInst;
9595
class CallBrInst;
96+
class GetElementPtrInst;
9697

9798
/// Iterator for the `Use` edges of a User's operands.
9899
/// \Returns the operand `Use` when dereferenced.
@@ -196,18 +197,19 @@ class Value {
196197
/// order.
197198
llvm::Value *Val = nullptr;
198199

199-
friend class Context; // For getting `Val`.
200-
friend class User; // For getting `Val`.
201-
friend class Use; // For getting `Val`.
202-
friend class SelectInst; // For getting `Val`.
203-
friend class BranchInst; // For getting `Val`.
204-
friend class LoadInst; // For getting `Val`.
205-
friend class StoreInst; // For getting `Val`.
206-
friend class ReturnInst; // For getting `Val`.
207-
friend class CallBase; // For getting `Val`.
208-
friend class CallInst; // For getting `Val`.
209-
friend class InvokeInst; // For getting `Val`.
210-
friend class CallBrInst; // For getting `Val`.
200+
friend class Context; // For getting `Val`.
201+
friend class User; // For getting `Val`.
202+
friend class Use; // For getting `Val`.
203+
friend class SelectInst; // For getting `Val`.
204+
friend class BranchInst; // For getting `Val`.
205+
friend class LoadInst; // For getting `Val`.
206+
friend class StoreInst; // For getting `Val`.
207+
friend class ReturnInst; // For getting `Val`.
208+
friend class CallBase; // For getting `Val`.
209+
friend class CallInst; // For getting `Val`.
210+
friend class InvokeInst; // For getting `Val`.
211+
friend class CallBrInst; // For getting `Val`.
212+
friend class GetElementPtrInst; // For getting `Val`.
211213

212214
/// All values point to the context.
213215
Context &Ctx;
@@ -540,14 +542,15 @@ class Instruction : public sandboxir::User {
540542
/// A SandboxIR Instruction may map to multiple LLVM IR Instruction. This
541543
/// returns its topmost LLVM IR instruction.
542544
llvm::Instruction *getTopmostLLVMInstruction() const;
543-
friend class SelectInst; // For getTopmostLLVMInstruction().
544-
friend class BranchInst; // For getTopmostLLVMInstruction().
545-
friend class LoadInst; // For getTopmostLLVMInstruction().
546-
friend class StoreInst; // For getTopmostLLVMInstruction().
547-
friend class ReturnInst; // For getTopmostLLVMInstruction().
548-
friend class CallInst; // For getTopmostLLVMInstruction().
549-
friend class InvokeInst; // For getTopmostLLVMInstruction().
550-
friend class CallBrInst; // For getTopmostLLVMInstruction().
545+
friend class SelectInst; // For getTopmostLLVMInstruction().
546+
friend class BranchInst; // For getTopmostLLVMInstruction().
547+
friend class LoadInst; // For getTopmostLLVMInstruction().
548+
friend class StoreInst; // For getTopmostLLVMInstruction().
549+
friend class ReturnInst; // For getTopmostLLVMInstruction().
550+
friend class CallInst; // For getTopmostLLVMInstruction().
551+
friend class InvokeInst; // For getTopmostLLVMInstruction().
552+
friend class CallBrInst; // For getTopmostLLVMInstruction().
553+
friend class GetElementPtrInst; // For getTopmostLLVMInstruction().
551554

552555
/// \Returns the LLVM IR Instructions that this SandboxIR maps to in program
553556
/// order.
@@ -1175,6 +1178,110 @@ class CallBrInst final : public CallBase {
11751178
#endif
11761179
};
11771180

1181+
class GetElementPtrInst final : public Instruction {
1182+
/// Use Context::createGetElementPtrInst(). Don't call
1183+
/// the constructor directly.
1184+
GetElementPtrInst(llvm::Instruction *I, Context &Ctx)
1185+
: Instruction(ClassID::GetElementPtr, Opcode::GetElementPtr, I, Ctx) {}
1186+
GetElementPtrInst(ClassID SubclassID, llvm::Instruction *I, Context &Ctx)
1187+
: Instruction(SubclassID, Opcode::GetElementPtr, I, Ctx) {}
1188+
friend class Context; // For accessing the constructor in
1189+
// create*()
1190+
Use getOperandUseInternal(unsigned OpIdx, bool Verify) const final {
1191+
return getOperandUseDefault(OpIdx, Verify);
1192+
}
1193+
SmallVector<llvm::Instruction *, 1> getLLVMInstrs() const final {
1194+
return {cast<llvm::Instruction>(Val)};
1195+
}
1196+
1197+
public:
1198+
static Value *create(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
1199+
BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx,
1200+
const Twine &NameStr = "");
1201+
static Value *create(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
1202+
Instruction *InsertBefore, Context &Ctx,
1203+
const Twine &NameStr = "");
1204+
static Value *create(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
1205+
BasicBlock *InsertAtEnd, Context &Ctx,
1206+
const Twine &NameStr = "");
1207+
1208+
static bool classof(const Value *From) {
1209+
return From->getSubclassID() == ClassID::GetElementPtr;
1210+
}
1211+
unsigned getUseOperandNo(const Use &Use) const final {
1212+
return getUseOperandNoDefault(Use);
1213+
}
1214+
unsigned getNumOfIRInstrs() const final { return 1u; }
1215+
1216+
Type *getSourceElementType() const {
1217+
return cast<llvm::GetElementPtrInst>(Val)->getSourceElementType();
1218+
}
1219+
Type *getResultElementType() const {
1220+
return cast<llvm::GetElementPtrInst>(Val)->getResultElementType();
1221+
}
1222+
unsigned getAddressSpace() const {
1223+
return cast<llvm::GetElementPtrInst>(Val)->getAddressSpace();
1224+
}
1225+
1226+
inline op_iterator idx_begin() { return op_begin() + 1; }
1227+
inline const_op_iterator idx_begin() const {
1228+
return const_cast<GetElementPtrInst *>(this)->idx_begin();
1229+
}
1230+
inline op_iterator idx_end() { return op_end(); }
1231+
inline const_op_iterator idx_end() const {
1232+
return const_cast<GetElementPtrInst *>(this)->idx_end();
1233+
}
1234+
inline iterator_range<op_iterator> indices() {
1235+
return make_range(idx_begin(), idx_end());
1236+
}
1237+
inline iterator_range<const_op_iterator> indices() const {
1238+
return const_cast<GetElementPtrInst *>(this)->indices();
1239+
}
1240+
1241+
Value *getPointerOperand() const;
1242+
static unsigned getPointerOperandIndex() {
1243+
return llvm::GetElementPtrInst::getPointerOperandIndex();
1244+
}
1245+
Type *getPointerOperandType() const {
1246+
return cast<llvm::GetElementPtrInst>(Val)->getPointerOperandType();
1247+
}
1248+
unsigned getPointerAddressSpace() const {
1249+
return cast<llvm::GetElementPtrInst>(Val)->getPointerAddressSpace();
1250+
}
1251+
unsigned getNumIndices() const {
1252+
return cast<llvm::GetElementPtrInst>(Val)->getNumIndices();
1253+
}
1254+
bool hasIndices() const {
1255+
return cast<llvm::GetElementPtrInst>(Val)->hasIndices();
1256+
}
1257+
bool hasAllConstantIndices() const {
1258+
return cast<llvm::GetElementPtrInst>(Val)->hasAllConstantIndices();
1259+
}
1260+
GEPNoWrapFlags getNoWrapFlags() const {
1261+
return cast<llvm::GetElementPtrInst>(Val)->getNoWrapFlags();
1262+
}
1263+
bool isInBounds() const {
1264+
return cast<llvm::GetElementPtrInst>(Val)->isInBounds();
1265+
}
1266+
bool hasNoUnsignedSignedWrap() const {
1267+
return cast<llvm::GetElementPtrInst>(Val)->hasNoUnsignedSignedWrap();
1268+
}
1269+
bool hasNoUnsignedWrap() const {
1270+
return cast<llvm::GetElementPtrInst>(Val)->hasNoUnsignedWrap();
1271+
}
1272+
bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const {
1273+
return cast<llvm::GetElementPtrInst>(Val)->accumulateConstantOffset(DL,
1274+
Offset);
1275+
}
1276+
// TODO: Add missing member functions.
1277+
1278+
#ifndef NDEBUG
1279+
void verify() const final {}
1280+
void dump(raw_ostream &OS) const override;
1281+
LLVM_DUMP_METHOD void dump() const override;
1282+
#endif
1283+
};
1284+
11781285
/// An LLLVM Instruction that has no SandboxIR equivalent class gets mapped to
11791286
/// an OpaqueInstr.
11801287
class OpaqueInst : public sandboxir::Instruction {
@@ -1329,6 +1436,8 @@ class Context {
13291436
friend InvokeInst; // For createInvokeInst()
13301437
CallBrInst *createCallBrInst(llvm::CallBrInst *I);
13311438
friend CallBrInst; // For createCallBrInst()
1439+
GetElementPtrInst *createGetElementPtrInst(llvm::GetElementPtrInst *I);
1440+
friend GetElementPtrInst; // For createGetElementPtrInst()
13321441

13331442
public:
13341443
Context(LLVMContext &LLVMCtx)

llvm/include/llvm/SandboxIR/SandboxIRValues.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ DEF_INSTR(Ret, OP(Ret), ReturnInst)
3333
DEF_INSTR(Call, OP(Call), CallInst)
3434
DEF_INSTR(Invoke, OP(Invoke), InvokeInst)
3535
DEF_INSTR(CallBr, OP(CallBr), CallBrInst)
36+
DEF_INSTR(GetElementPtr, OP(GetElementPtr), GetElementPtrInst)
3637

3738
#ifdef DEF_VALUE
3839
#undef DEF_VALUE

llvm/lib/SandboxIR/SandboxIR.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -996,6 +996,60 @@ void CallBrInst::dump() const {
996996
dump(dbgs());
997997
dbgs() << "\n";
998998
}
999+
#endif // NDEBUG
1000+
1001+
Value *GetElementPtrInst::create(Type *Ty, Value *Ptr,
1002+
ArrayRef<Value *> IdxList,
1003+
BasicBlock::iterator WhereIt,
1004+
BasicBlock *WhereBB, Context &Ctx,
1005+
const Twine &NameStr) {
1006+
auto &Builder = Ctx.getLLVMIRBuilder();
1007+
if (WhereIt != WhereBB->end())
1008+
Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
1009+
else
1010+
Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
1011+
SmallVector<llvm::Value *> LLVMIdxList;
1012+
LLVMIdxList.reserve(IdxList.size());
1013+
for (Value *Idx : IdxList)
1014+
LLVMIdxList.push_back(Idx->Val);
1015+
llvm::Value *NewV = Builder.CreateGEP(Ty, Ptr->Val, LLVMIdxList, NameStr);
1016+
if (auto *NewGEP = dyn_cast<llvm::GetElementPtrInst>(NewV))
1017+
return Ctx.createGetElementPtrInst(NewGEP);
1018+
assert(isa<llvm::Constant>(NewV) && "Expected constant");
1019+
return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1020+
}
1021+
1022+
Value *GetElementPtrInst::create(Type *Ty, Value *Ptr,
1023+
ArrayRef<Value *> IdxList,
1024+
Instruction *InsertBefore, Context &Ctx,
1025+
const Twine &NameStr) {
1026+
return GetElementPtrInst::create(Ty, Ptr, IdxList,
1027+
InsertBefore->getIterator(),
1028+
InsertBefore->getParent(), Ctx, NameStr);
1029+
}
1030+
1031+
Value *GetElementPtrInst::create(Type *Ty, Value *Ptr,
1032+
ArrayRef<Value *> IdxList,
1033+
BasicBlock *InsertAtEnd, Context &Ctx,
1034+
const Twine &NameStr) {
1035+
return GetElementPtrInst::create(Ty, Ptr, IdxList, InsertAtEnd->end(),
1036+
InsertAtEnd, Ctx, NameStr);
1037+
}
1038+
1039+
Value *GetElementPtrInst::getPointerOperand() const {
1040+
return Ctx.getValue(cast<llvm::GetElementPtrInst>(Val)->getPointerOperand());
1041+
}
1042+
1043+
#ifndef NDEBUG
1044+
void GetElementPtrInst::dump(raw_ostream &OS) const {
1045+
dumpCommonPrefix(OS);
1046+
dumpCommonSuffix(OS);
1047+
}
1048+
1049+
void GetElementPtrInst::dump() const {
1050+
dump(dbgs());
1051+
dbgs() << "\n";
1052+
}
9991053

10001054
void OpaqueInst::dump(raw_ostream &OS) const {
10011055
dumpCommonPrefix(OS);
@@ -1165,6 +1219,12 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
11651219
It->second = std::unique_ptr<CallBrInst>(new CallBrInst(LLVMCallBr, *this));
11661220
return It->second.get();
11671221
}
1222+
case llvm::Instruction::GetElementPtr: {
1223+
auto *LLVMGEP = cast<llvm::GetElementPtrInst>(LLVMV);
1224+
It->second = std::unique_ptr<GetElementPtrInst>(
1225+
new GetElementPtrInst(LLVMGEP, *this));
1226+
return It->second.get();
1227+
}
11681228
default:
11691229
break;
11701230
}
@@ -1223,6 +1283,13 @@ CallBrInst *Context::createCallBrInst(llvm::CallBrInst *I) {
12231283
return cast<CallBrInst>(registerValue(std::move(NewPtr)));
12241284
}
12251285

1286+
GetElementPtrInst *
1287+
Context::createGetElementPtrInst(llvm::GetElementPtrInst *I) {
1288+
auto NewPtr =
1289+
std::unique_ptr<GetElementPtrInst>(new GetElementPtrInst(I, *this));
1290+
return cast<GetElementPtrInst>(registerValue(std::move(NewPtr)));
1291+
}
1292+
12261293
Value *Context::getValue(llvm::Value *V) const {
12271294
auto It = LLVMValueToValueMap.find(V);
12281295
if (It != LLVMValueToValueMap.end())

0 commit comments

Comments
 (0)