[llvm] [SandboxIR] Implement AllocaInst (PR #102027)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 6 10:39:22 PDT 2024
https://github.com/vporpo updated https://github.com/llvm/llvm-project/pull/102027
>From f5b9bb3b7db7bc2f7a83e68f81e4b06bfd3d50da Mon Sep 17 00:00:00 2001
From: Vasileios Porpodas <vporpodas at google.com>
Date: Thu, 1 Aug 2024 10:37:49 -0700
Subject: [PATCH 1/3] [SandboxIR] Implement AllocaInst
This patch implements sandboxir::AllocaInst which mirrors llvm::AllocaInst.
---
llvm/include/llvm/SandboxIR/SandboxIR.h | 107 +++++++++++++
.../llvm/SandboxIR/SandboxIRValues.def | 1 +
llvm/include/llvm/SandboxIR/Tracker.h | 69 ++++++++
llvm/lib/SandboxIR/SandboxIR.cpp | 84 +++++++++-
llvm/lib/SandboxIR/Tracker.cpp | 52 ++++++
llvm/unittests/SandboxIR/SandboxIRTest.cpp | 148 ++++++++++++++++++
llvm/unittests/SandboxIR/TrackerTest.cpp | 55 +++++++
7 files changed, 515 insertions(+), 1 deletion(-)
diff --git a/llvm/include/llvm/SandboxIR/SandboxIR.h b/llvm/include/llvm/SandboxIR/SandboxIR.h
index 9e5db20b24877..89741894b95ef 100644
--- a/llvm/include/llvm/SandboxIR/SandboxIR.h
+++ b/llvm/include/llvm/SandboxIR/SandboxIR.h
@@ -124,6 +124,7 @@ class GetElementPtrInst;
class CastInst;
class PtrToIntInst;
class BitCastInst;
+class AllocaInst;
/// Iterator for the `Use` edges of a User's operands.
/// \Returns the operand `Use` when dereferenced.
@@ -240,6 +241,7 @@ class Value {
friend class InvokeInst; // For getting `Val`.
friend class CallBrInst; // For getting `Val`.
friend class GetElementPtrInst; // For getting `Val`.
+ friend class AllocaInst; // For getting `Val`.
friend class CastInst; // For getting `Val`.
friend class PHINode; // For getting `Val`.
@@ -633,6 +635,7 @@ class Instruction : public sandboxir::User {
friend class InvokeInst; // For getTopmostLLVMInstruction().
friend class CallBrInst; // For getTopmostLLVMInstruction().
friend class GetElementPtrInst; // For getTopmostLLVMInstruction().
+ friend class AllocaInst; // For getTopmostLLVMInstruction().
friend class CastInst; // For getTopmostLLVMInstruction().
friend class PHINode; // For getTopmostLLVMInstruction().
@@ -1393,6 +1396,108 @@ class GetElementPtrInst final : public Instruction {
#endif
};
+class AllocaInst final : public UnaryInstruction {
+ Use getOperandUseInternal(unsigned OpIdx, bool Verify) const final {
+ return getOperandUseDefault(OpIdx, Verify);
+ }
+ SmallVector<llvm::Instruction *, 1> getLLVMInstrs() const final {
+ return {cast<llvm::Instruction>(Val)};
+ }
+
+public:
+ AllocaInst(llvm::AllocaInst *AI, Context &Ctx)
+ : UnaryInstruction(ClassID::Alloca, Instruction::Opcode::Alloca, AI,
+ Ctx) {}
+
+ static AllocaInst *create(Type *Ty, unsigned AddrSpace, BBIterator WhereIt,
+ BasicBlock *WhereBB, Context &Ctx,
+ Value *ArraySize = nullptr, const Twine &Name = "");
+ static AllocaInst *create(Type *Ty, unsigned AddrSpace,
+ Instruction *InsertBefore, Context &Ctx,
+ Value *ArraySize = nullptr, const Twine &Name = "");
+ static AllocaInst *create(Type *Ty, unsigned AddrSpace,
+ BasicBlock *InsertAtEnd, Context &Ctx,
+ Value *ArraySize = nullptr, const Twine &Name = "");
+
+ unsigned getUseOperandNo(const Use &Use) const final {
+ return getUseOperandNoDefault(Use);
+ }
+ unsigned getNumOfIRInstrs() const final { return 1u; }
+
+ /// Return true if there is an allocation size parameter to the allocation
+ /// instruction that is not 1.
+ bool isArrayAllocation() const {
+ return cast<llvm::AllocaInst>(Val)->isArrayAllocation();
+ }
+ /// Get the number of elements allocated. For a simple allocation of a single
+ /// element, this will return a constant 1 value.
+ Value *getArraySize();
+ const Value *getArraySize() const {
+ return const_cast<AllocaInst *>(this)->getArraySize();
+ }
+ /// Overload to return most specific pointer type.
+ PointerType *getType() const {
+ return cast<llvm::AllocaInst>(Val)->getType();
+ }
+ /// Return the address space for the allocation.
+ unsigned getAddressSpace() const {
+ return cast<llvm::AllocaInst>(Val)->getAddressSpace();
+ }
+ /// Get allocation size in bytes. Returns std::nullopt if size can't be
+ /// determined, e.g. in case of a VLA.
+ std::optional<TypeSize> getAllocationSize(const DataLayout &DL) const {
+ return cast<llvm::AllocaInst>(Val)->getAllocationSize(DL);
+ }
+ /// Get allocation size in bits. Returns std::nullopt if size can't be
+ /// determined, e.g. in case of a VLA.
+ std::optional<TypeSize> getAllocationSizeInBits(const DataLayout &DL) const {
+ return cast<llvm::AllocaInst>(Val)->getAllocationSizeInBits(DL);
+ }
+ /// Return the type that is being allocated by the instruction.
+ Type *getAllocatedType() const {
+ return cast<llvm::AllocaInst>(Val)->getAllocatedType();
+ }
+ /// for use only in special circumstances that need to generically
+ /// transform a whole instruction (eg: IR linking and vectorization).
+ void setAllocatedType(Type *Ty);
+ /// Return the alignment of the memory that is being allocated by the
+ /// instruction.
+ Align getAlign() const { return cast<llvm::AllocaInst>(Val)->getAlign(); }
+ void setAlignment(Align Align);
+ /// Return true if this alloca is in the entry block of the function and is a
+ /// constant size. If so, the code generator will fold it into the
+ /// prolog/epilog code, so it is basically free.
+ bool isStaticAlloca() const {
+ return cast<llvm::AllocaInst>(Val)->isStaticAlloca();
+ }
+ /// Return true if this alloca is used as an inalloca argument to a call. Such
+ /// allocas are never considered static even if they are in the entry block.
+ bool isUsedWithInAlloca() const {
+ return cast<llvm::AllocaInst>(Val)->isUsedWithInAlloca();
+ }
+ /// Specify whether this alloca is used to represent the arguments to a call.
+ void setUsedWithInAlloca(bool V);
+ /// Return true if this alloca is used as a swifterror argument to a call.
+ bool isSwiftError() const {
+ return cast<llvm::AllocaInst>(Val)->isSwiftError();
+ }
+ /// Specify whether this alloca is used to represent a swifterror.
+ void setSwiftError(bool V);
+
+ static bool classof(const Value *From) {
+ if (auto *I = dyn_cast<Instruction>(From))
+ return I->getSubclassID() == Instruction::ClassID::Alloca;
+ return false;
+ }
+#ifndef NDEBUG
+ void verify() const final {
+ assert(isa<llvm::AllocaInst>(Val) && "Expected AllocaInst!");
+ }
+ void dump(raw_ostream &OS) const override;
+ LLVM_DUMP_METHOD void dump() const override;
+#endif
+};
+
class CastInst : public UnaryInstruction {
static Opcode getCastOpcode(llvm::Instruction::CastOps CastOp) {
switch (CastOp) {
@@ -1727,6 +1832,8 @@ class Context {
friend CallBrInst; // For createCallBrInst()
GetElementPtrInst *createGetElementPtrInst(llvm::GetElementPtrInst *I);
friend GetElementPtrInst; // For createGetElementPtrInst()
+ AllocaInst *createAllocaInst(llvm::AllocaInst *I);
+ friend AllocaInst; // For createAllocaInst()
CastInst *createCastInst(llvm::CastInst *I);
friend CastInst; // For createCastInst()
PHINode *createPHINode(llvm::PHINode *I);
diff --git a/llvm/include/llvm/SandboxIR/SandboxIRValues.def b/llvm/include/llvm/SandboxIR/SandboxIRValues.def
index 4cb601128a507..3b16bdee6d15c 100644
--- a/llvm/include/llvm/SandboxIR/SandboxIRValues.def
+++ b/llvm/include/llvm/SandboxIR/SandboxIRValues.def
@@ -43,6 +43,7 @@ DEF_INSTR(Call, OP(Call), CallInst)
DEF_INSTR(Invoke, OP(Invoke), InvokeInst)
DEF_INSTR(CallBr, OP(CallBr), CallBrInst)
DEF_INSTR(GetElementPtr, OP(GetElementPtr), GetElementPtrInst)
+DEF_INSTR(Alloca, OP(Alloca), AllocaInst)
DEF_INSTR(Cast, OPCODES(\
OP(ZExt) \
OP(SExt) \
diff --git a/llvm/include/llvm/SandboxIR/Tracker.h b/llvm/include/llvm/SandboxIR/Tracker.h
index 3c491bf0b3f58..3fb52439caef2 100644
--- a/llvm/include/llvm/SandboxIR/Tracker.h
+++ b/llvm/include/llvm/SandboxIR/Tracker.h
@@ -58,6 +58,7 @@ class LoadInst;
class StoreInst;
class Instruction;
class Tracker;
+class AllocaInst;
/// The base class for IR Change classes.
class IRChangeBase {
@@ -255,6 +256,74 @@ class CallBrInstSetDefaultDest : public IRChangeBase {
#endif
};
+class AllocaSetAllocatedType final : public IRChangeBase {
+ AllocaInst *Alloca;
+ Type *OrigType;
+
+public:
+ AllocaSetAllocatedType(AllocaInst *Alloca, Tracker &Tracker);
+ void revert() final;
+ void accept() final {}
+#ifndef NDEBUG
+ void dump(raw_ostream &OS) const final {
+ dumpCommon(OS);
+ OS << "AllocaSetAllocatedType";
+ }
+ LLVM_DUMP_METHOD void dump() const final;
+#endif
+};
+
+class AllocaSetAlignment final : public IRChangeBase {
+ AllocaInst *Alloca;
+ Align OrigAlign;
+
+public:
+ AllocaSetAlignment(AllocaInst *Alloca, Tracker &Tracker);
+ void revert() final;
+ void accept() final {}
+#ifndef NDEBUG
+ void dump(raw_ostream &OS) const final {
+ dumpCommon(OS);
+ OS << "AllocaSetAlignment";
+ }
+ LLVM_DUMP_METHOD void dump() const final;
+#endif
+};
+
+class AllocaSetUsedWithInAlloca final : public IRChangeBase {
+ AllocaInst *Alloca;
+ bool Orig;
+
+public:
+ AllocaSetUsedWithInAlloca(AllocaInst *Alloca, Tracker &Tracker);
+ void revert() final;
+ void accept() final {}
+#ifndef NDEBUG
+ void dump(raw_ostream &OS) const final {
+ dumpCommon(OS);
+ OS << "AllocaSetUsedWithInAlloca";
+ }
+ LLVM_DUMP_METHOD void dump() const final;
+#endif
+};
+
+class AllocaSetSwiftError final : public IRChangeBase {
+ AllocaInst *Alloca;
+ bool Orig;
+
+public:
+ AllocaSetSwiftError(AllocaInst *Alloca, Tracker &Tracker);
+ void revert() final;
+ void accept() final {}
+#ifndef NDEBUG
+ void dump(raw_ostream &OS) const final {
+ dumpCommon(OS);
+ OS << "AllocaSetSwiftError";
+ }
+ LLVM_DUMP_METHOD void dump() const final;
+#endif
+};
+
class CallBrInstSetIndirectDest : public IRChangeBase {
CallBrInst *CallBr;
unsigned Idx;
diff --git a/llvm/lib/SandboxIR/SandboxIR.cpp b/llvm/lib/SandboxIR/SandboxIR.cpp
index 235c4574ead13..afd9d1f87e605 100644
--- a/llvm/lib/SandboxIR/SandboxIR.cpp
+++ b/llvm/lib/SandboxIR/SandboxIR.cpp
@@ -1212,6 +1212,80 @@ static llvm::Instruction::CastOps getLLVMCastOp(Instruction::Opcode Opc) {
}
}
+AllocaInst *AllocaInst::create(Type *Ty, unsigned AddrSpace, BBIterator WhereIt,
+ BasicBlock *WhereBB, Context &Ctx,
+ Value *ArraySize, const Twine &Name) {
+ auto &Builder = Ctx.getLLVMIRBuilder();
+ if (WhereIt == WhereBB->end())
+ Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
+ else
+ Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
+ auto *NewAlloca = Builder.CreateAlloca(Ty, AddrSpace, ArraySize->Val, Name);
+ return Ctx.createAllocaInst(NewAlloca);
+}
+
+AllocaInst *AllocaInst::create(Type *Ty, unsigned AddrSpace,
+ Instruction *InsertBefore, Context &Ctx,
+ Value *ArraySize, const Twine &Name) {
+ return create(Ty, AddrSpace, InsertBefore->getIterator(),
+ InsertBefore->getParent(), Ctx, ArraySize, Name);
+}
+
+AllocaInst *AllocaInst::create(Type *Ty, unsigned AddrSpace,
+ BasicBlock *InsertAtEnd, Context &Ctx,
+ Value *ArraySize, const Twine &Name) {
+ return create(Ty, AddrSpace, InsertAtEnd->end(), InsertAtEnd, Ctx, ArraySize,
+ Name);
+}
+
+void AllocaInst::setAllocatedType(Type *Ty) {
+ auto &Tracker = Ctx.getTracker();
+ if (Tracker.isTracking())
+ Tracker.track(std::make_unique<AllocaSetAllocatedType>(
+ cast<AllocaInst>(this), Tracker));
+ cast<llvm::AllocaInst>(Val)->setAllocatedType(Ty);
+}
+
+void AllocaInst::setAlignment(Align Align) {
+ auto &Tracker = Ctx.getTracker();
+ if (Tracker.isTracking())
+ Tracker.track(
+ std::make_unique<AllocaSetAlignment>(cast<AllocaInst>(this), Tracker));
+ cast<llvm::AllocaInst>(Val)->setAlignment(Align);
+}
+
+void AllocaInst::setUsedWithInAlloca(bool V) {
+ auto &Tracker = Ctx.getTracker();
+ if (Tracker.isTracking())
+ Tracker.track(std::make_unique<AllocaSetUsedWithInAlloca>(
+ cast<AllocaInst>(this), Tracker));
+ cast<llvm::AllocaInst>(Val)->setUsedWithInAlloca(V);
+}
+
+void AllocaInst::setSwiftError(bool V) {
+ auto &Tracker = Ctx.getTracker();
+ if (Tracker.isTracking())
+ Tracker.track(
+ std::make_unique<AllocaSetSwiftError>(cast<AllocaInst>(this), Tracker));
+ cast<llvm::AllocaInst>(Val)->setSwiftError(V);
+}
+
+Value *AllocaInst::getArraySize() {
+ return Ctx.getValue(cast<llvm::AllocaInst>(Val)->getArraySize());
+}
+
+#ifndef NDEBUG
+void AllocaInst::dump(raw_ostream &OS) const {
+ dumpCommonPrefix(OS);
+ dumpCommonSuffix(OS);
+}
+
+void AllocaInst::dump() const {
+ dump(dbgs());
+ dbgs() << "\n";
+}
+#endif // NDEBUG
+
Value *CastInst::create(Type *DestTy, Opcode Op, Value *Operand,
BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx,
const Twine &Name) {
@@ -1452,6 +1526,11 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
new GetElementPtrInst(LLVMGEP, *this));
return It->second.get();
}
+ case llvm::Instruction::Alloca: {
+ auto *LLVMAlloca = cast<llvm::AllocaInst>(LLVMV);
+ It->second = std::unique_ptr<AllocaInst>(new AllocaInst(LLVMAlloca, *this));
+ return It->second.get();
+ }
case llvm::Instruction::ZExt:
case llvm::Instruction::SExt:
case llvm::Instruction::FPToUI:
@@ -1538,7 +1617,10 @@ Context::createGetElementPtrInst(llvm::GetElementPtrInst *I) {
std::unique_ptr<GetElementPtrInst>(new GetElementPtrInst(I, *this));
return cast<GetElementPtrInst>(registerValue(std::move(NewPtr)));
}
-
+AllocaInst *Context::createAllocaInst(llvm::AllocaInst *I) {
+ auto NewPtr = std::unique_ptr<AllocaInst>(new AllocaInst(I, *this));
+ return cast<AllocaInst>(registerValue(std::move(NewPtr)));
+}
CastInst *Context::createCastInst(llvm::CastInst *I) {
auto NewPtr = std::unique_ptr<CastInst>(new CastInst(I, *this));
return cast<CastInst>(registerValue(std::move(NewPtr)));
diff --git a/llvm/lib/SandboxIR/Tracker.cpp b/llvm/lib/SandboxIR/Tracker.cpp
index aa18c21cd03d6..90a9df3c96f31 100644
--- a/llvm/lib/SandboxIR/Tracker.cpp
+++ b/llvm/lib/SandboxIR/Tracker.cpp
@@ -204,6 +204,58 @@ void RemoveFromParent::dump() const {
}
#endif
+AllocaSetAllocatedType::AllocaSetAllocatedType(AllocaInst *Alloca,
+ Tracker &Tracker)
+ : IRChangeBase(Tracker), Alloca(Alloca),
+ OrigType(Alloca->getAllocatedType()) {}
+
+void AllocaSetAllocatedType::revert() { Alloca->setAllocatedType(OrigType); }
+
+#ifndef NDEBUG
+void AllocaSetAllocatedType::dump() const {
+ dump(dbgs());
+ dbgs() << "\n";
+}
+#endif // NDEBUG
+
+AllocaSetAlignment::AllocaSetAlignment(AllocaInst *Alloca, Tracker &Tracker)
+ : IRChangeBase(Tracker), Alloca(Alloca), OrigAlign(Alloca->getAlign()) {}
+
+void AllocaSetAlignment::revert() { Alloca->setAlignment(OrigAlign); }
+
+#ifndef NDEBUG
+void AllocaSetAlignment::dump() const {
+ dump(dbgs());
+ dbgs() << "\n";
+}
+#endif // NDEBUG
+
+AllocaSetUsedWithInAlloca::AllocaSetUsedWithInAlloca(AllocaInst *Alloca,
+ Tracker &Tracker)
+ : IRChangeBase(Tracker), Alloca(Alloca),
+ Orig(Alloca->isUsedWithInAlloca()) {}
+
+void AllocaSetUsedWithInAlloca::revert() { Alloca->setUsedWithInAlloca(Orig); }
+
+#ifndef NDEBUG
+void AllocaSetUsedWithInAlloca::dump() const {
+ dump(dbgs());
+ dbgs() << "\n";
+}
+#endif // NDEBUG
+
+AllocaSetSwiftError::AllocaSetSwiftError(AllocaInst *Alloca, Tracker &Tracker)
+ : IRChangeBase(Tracker), Alloca(Alloca), Orig(Alloca->isSwiftError()) {}
+
+void AllocaSetSwiftError::revert() { Alloca->setSwiftError(Orig); }
+
+#ifndef NDEBUG
+void AllocaSetSwiftError::dump() const {
+ dump(dbgs());
+ dbgs() << "\n";
+}
+#endif // NDEBUG
+
CallBrInstSetDefaultDest::CallBrInstSetDefaultDest(CallBrInst *CallBr,
Tracker &Tracker)
: IRChangeBase(Tracker), CallBr(CallBr) {
diff --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
index 550c0576e0237..d53e6d872e628 100644
--- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp
+++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
@@ -1475,6 +1475,154 @@ define void @foo(ptr %ptr, <2 x ptr> %ptrs) {
EXPECT_EQ(NewGEP2->getNextNode(), nullptr);
}
+TEST_F(SandboxIRTest, AllocaInst) {
+ parseIR(C, R"IR(
+define void @foo() {
+ %allocaScalar = alloca i32, align 1024
+ %allocaArray = alloca i32, i32 42
+ ret void
+}
+)IR");
+ DataLayout DL(M.get());
+ llvm::Function &LLVMF = *M->getFunction("foo");
+ llvm::BasicBlock *LLVMBB = &*LLVMF.begin();
+ auto LLVMIt = LLVMBB->begin();
+ auto *LLVMAllocaScalar = cast<llvm::AllocaInst>(&*LLVMIt++);
+ auto *LLVMAllocaArray = cast<llvm::AllocaInst>(&*LLVMIt++);
+
+ sandboxir::Context Ctx(C);
+ sandboxir::Function *F = Ctx.createFunction(&LLVMF);
+ auto *BB = &*F->begin();
+ auto It = BB->begin();
+ auto *AllocaScalar = cast<sandboxir::AllocaInst>(&*It++);
+ auto *AllocaArray = cast<sandboxir::AllocaInst>(&*It++);
+ auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
+
+ // Check isArrayAllocation().
+ EXPECT_EQ(AllocaScalar->isArrayAllocation(),
+ LLVMAllocaScalar->isArrayAllocation());
+ EXPECT_EQ(AllocaArray->isArrayAllocation(),
+ LLVMAllocaArray->isArrayAllocation());
+ // Check getArraySize().
+ EXPECT_EQ(AllocaScalar->getArraySize(),
+ Ctx.getValue(LLVMAllocaScalar->getArraySize()));
+ EXPECT_EQ(AllocaArray->getArraySize(),
+ Ctx.getValue(LLVMAllocaArray->getArraySize()));
+ // Check getType().
+ EXPECT_EQ(AllocaScalar->getType(), LLVMAllocaScalar->getType());
+ EXPECT_EQ(AllocaArray->getType(), LLVMAllocaArray->getType());
+ // Check getAddressSpace().
+ EXPECT_EQ(AllocaScalar->getAddressSpace(),
+ LLVMAllocaScalar->getAddressSpace());
+ EXPECT_EQ(AllocaArray->getAddressSpace(), LLVMAllocaArray->getAddressSpace());
+ // Check getAllocationSize().
+ EXPECT_EQ(AllocaScalar->getAllocationSize(DL),
+ LLVMAllocaScalar->getAllocationSize(DL));
+ EXPECT_EQ(AllocaArray->getAllocationSize(DL),
+ LLVMAllocaArray->getAllocationSize(DL));
+ // Check getAllocationSizeInBits().
+ EXPECT_EQ(AllocaScalar->getAllocationSizeInBits(DL),
+ LLVMAllocaScalar->getAllocationSizeInBits(DL));
+ EXPECT_EQ(AllocaArray->getAllocationSizeInBits(DL),
+ LLVMAllocaArray->getAllocationSizeInBits(DL));
+ // Check getAllocatedType().
+ EXPECT_EQ(AllocaScalar->getAllocatedType(),
+ LLVMAllocaScalar->getAllocatedType());
+ EXPECT_EQ(AllocaArray->getAllocatedType(),
+ LLVMAllocaArray->getAllocatedType());
+ // Check setAllocatedType().
+ auto *OrigType = AllocaScalar->getAllocatedType();
+ auto *NewType = PointerType::get(C, 0);
+ EXPECT_NE(NewType, OrigType);
+ AllocaScalar->setAllocatedType(NewType);
+ EXPECT_EQ(AllocaScalar->getAllocatedType(), NewType);
+ AllocaScalar->setAllocatedType(OrigType);
+ EXPECT_EQ(AllocaScalar->getAllocatedType(), OrigType);
+ // Check getAlign().
+ EXPECT_EQ(AllocaScalar->getAlign(), LLVMAllocaScalar->getAlign());
+ EXPECT_EQ(AllocaArray->getAlign(), LLVMAllocaArray->getAlign());
+ // Check setAlignment().
+ Align OrigAlign = AllocaScalar->getAlign();
+ Align NewAlign(16);
+ EXPECT_NE(NewAlign, OrigAlign);
+ AllocaScalar->setAlignment(NewAlign);
+ EXPECT_EQ(AllocaScalar->getAlign(), NewAlign);
+ AllocaScalar->setAlignment(OrigAlign);
+ EXPECT_EQ(AllocaScalar->getAlign(), OrigAlign);
+ // Check isStaticAlloca().
+ EXPECT_EQ(AllocaScalar->isStaticAlloca(), LLVMAllocaScalar->isStaticAlloca());
+ EXPECT_EQ(AllocaArray->isStaticAlloca(), LLVMAllocaArray->isStaticAlloca());
+ // Check isUsedWithInAlloca(), setUsedWithInAlloca().
+ EXPECT_EQ(AllocaScalar->isUsedWithInAlloca(),
+ LLVMAllocaScalar->isUsedWithInAlloca());
+ bool OrigUsedWithInAlloca = AllocaScalar->isUsedWithInAlloca();
+ bool NewUsedWithInAlloca = true;
+ EXPECT_NE(NewUsedWithInAlloca, OrigUsedWithInAlloca);
+ AllocaScalar->setUsedWithInAlloca(NewUsedWithInAlloca);
+ EXPECT_EQ(AllocaScalar->isUsedWithInAlloca(), NewUsedWithInAlloca);
+ AllocaScalar->setUsedWithInAlloca(OrigUsedWithInAlloca);
+ EXPECT_EQ(AllocaScalar->isUsedWithInAlloca(), OrigUsedWithInAlloca);
+ // Check isSwiftError(), setSwiftError().
+ EXPECT_EQ(AllocaScalar->isSwiftError(), LLVMAllocaScalar->isSwiftError());
+ bool OrigIsSwiftError = AllocaScalar->isSwiftError();
+ bool NewIsSwiftError = true;
+ EXPECT_NE(NewIsSwiftError, OrigIsSwiftError);
+ AllocaScalar->setSwiftError(NewIsSwiftError);
+ EXPECT_EQ(AllocaScalar->isSwiftError(), NewIsSwiftError);
+
+ auto *Ty = Type::getInt32Ty(C);
+ unsigned AddrSpace = 42;
+ auto *PtrTy = PointerType::get(C, AddrSpace);
+ auto *ArraySize = sandboxir::Constant::createInt(Ty, 43, Ctx);
+ {
+ // Check create() WhereIt, WhereBB.
+ auto *NewI = cast<sandboxir::AllocaInst>(sandboxir::AllocaInst::create(
+ Ty, AddrSpace, /*WhereIt=*/Ret->getIterator(),
+ /*WhereBB=*/Ret->getParent(), Ctx, ArraySize, "NewAlloca1"));
+ // Check getOpcode().
+ EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Alloca);
+ // Check getType().
+ EXPECT_EQ(NewI->getType(), PtrTy);
+ // Check getArraySize().
+ EXPECT_EQ(NewI->getArraySize(), ArraySize);
+ // Check getAddrSpace().
+ EXPECT_EQ(NewI->getAddressSpace(), AddrSpace);
+ // Check instr position.
+ EXPECT_EQ(NewI->getNextNode(), Ret);
+ }
+ {
+ // Check create() InsertBefore.
+ auto *NewI = cast<sandboxir::AllocaInst>(sandboxir::AllocaInst::create(
+ Ty, AddrSpace, /*InsertBefore=*/Ret, Ctx, ArraySize, "NewAlloca2"));
+ // Check getOpcode().
+ EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Alloca);
+ // Check getType().
+ EXPECT_EQ(NewI->getType(), PtrTy);
+ // Check getArraySize().
+ EXPECT_EQ(NewI->getArraySize(), ArraySize);
+ // Check getAddrSpace().
+ EXPECT_EQ(NewI->getAddressSpace(), AddrSpace);
+ // Check instr position.
+ EXPECT_EQ(NewI->getNextNode(), Ret);
+ }
+ {
+ // Check create() InsertAtEnd.
+ auto *NewI = cast<sandboxir::AllocaInst>(sandboxir::AllocaInst::create(
+ Ty, AddrSpace, /*InsertAtEnd=*/BB, Ctx, ArraySize, "NewAlloca3"));
+ // Check getOpcode().
+ EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Alloca);
+ // Check getType().
+ EXPECT_EQ(NewI->getType(), PtrTy);
+ // Check getArraySize().
+ EXPECT_EQ(NewI->getArraySize(), ArraySize);
+ // Check getAddrSpace().
+ EXPECT_EQ(NewI->getAddressSpace(), AddrSpace);
+ // Check instr position.
+ EXPECT_EQ(NewI->getParent(), BB);
+ EXPECT_EQ(NewI->getNextNode(), nullptr);
+ }
+}
+
TEST_F(SandboxIRTest, CastInst) {
parseIR(C, R"IR(
define void @foo(i32 %arg, float %farg, double %darg, ptr %ptr) {
diff --git a/llvm/unittests/SandboxIR/TrackerTest.cpp b/llvm/unittests/SandboxIR/TrackerTest.cpp
index e61258392a388..12dc6f452504f 100644
--- a/llvm/unittests/SandboxIR/TrackerTest.cpp
+++ b/llvm/unittests/SandboxIR/TrackerTest.cpp
@@ -644,6 +644,61 @@ define void @foo(i8 %arg) {
EXPECT_EQ(Invoke->getSuccessor(1), ExceptionBB);
}
+TEST_F(TrackerTest, AllocaInstSetters) {
+ parseIR(C, R"IR(
+define void @foo(i8 %arg) {
+ %alloca = alloca i32, align 64
+ ret void
+}
+)IR");
+ Function &LLVMF = *M->getFunction("foo");
+ sandboxir::Context Ctx(C);
+ auto &F = *Ctx.createFunction(&LLVMF);
+ auto *BB = &*F.begin();
+ auto It = BB->begin();
+ auto *Alloca = cast<sandboxir::AllocaInst>(&*It++);
+
+ // Check setAllocatedType().
+ Ctx.save();
+ auto *OrigTy = Alloca->getAllocatedType();
+ auto *NewTy = Type::getInt64Ty(C);
+ EXPECT_NE(NewTy, OrigTy);
+ Alloca->setAllocatedType(NewTy);
+ EXPECT_EQ(Alloca->getAllocatedType(), NewTy);
+ Ctx.revert();
+ EXPECT_EQ(Alloca->getAllocatedType(), OrigTy);
+
+ // Check setAlignment().
+ Ctx.save();
+ auto OrigAlign = Alloca->getAlign();
+ Align NewAlign(128);
+ EXPECT_NE(NewAlign, OrigAlign);
+ Alloca->setAlignment(NewAlign);
+ EXPECT_EQ(Alloca->getAlign(), NewAlign);
+ Ctx.revert();
+ EXPECT_EQ(Alloca->getAlign(), OrigAlign);
+
+ // Check setUsedWithInAlloca().
+ Ctx.save();
+ auto OrigWIA = Alloca->isUsedWithInAlloca();
+ bool NewWIA = true;
+ EXPECT_NE(NewWIA, OrigWIA);
+ Alloca->setUsedWithInAlloca(NewWIA);
+ EXPECT_EQ(Alloca->isUsedWithInAlloca(), NewWIA);
+ Ctx.revert();
+ EXPECT_EQ(Alloca->isUsedWithInAlloca(), OrigWIA);
+
+ // Check setSwiftError().
+ Ctx.save();
+ auto OrigSE = Alloca->isSwiftError();
+ bool NewSE = true;
+ EXPECT_NE(NewSE, OrigSE);
+ Alloca->setSwiftError(NewSE);
+ EXPECT_EQ(Alloca->isSwiftError(), NewSE);
+ Ctx.revert();
+ EXPECT_EQ(Alloca->isSwiftError(), OrigSE);
+}
+
TEST_F(TrackerTest, CallBrSetters) {
parseIR(C, R"IR(
define void @foo(i8 %arg) {
>From c1da45687a2549d5e238c1a225d39cff38b0d28d Mon Sep 17 00:00:00 2001
From: Vasileios Porpodas <vporpodas at google.com>
Date: Mon, 5 Aug 2024 11:20:20 -0700
Subject: [PATCH 2/3] fixup! [SandboxIR] Implement AllocaInst
Remove redundant cast<AllocaInst>(this).
---
llvm/lib/SandboxIR/SandboxIR.cpp | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/SandboxIR/SandboxIR.cpp b/llvm/lib/SandboxIR/SandboxIR.cpp
index afd9d1f87e605..e3017b15a7205 100644
--- a/llvm/lib/SandboxIR/SandboxIR.cpp
+++ b/llvm/lib/SandboxIR/SandboxIR.cpp
@@ -1241,32 +1241,28 @@ AllocaInst *AllocaInst::create(Type *Ty, unsigned AddrSpace,
void AllocaInst::setAllocatedType(Type *Ty) {
auto &Tracker = Ctx.getTracker();
if (Tracker.isTracking())
- Tracker.track(std::make_unique<AllocaSetAllocatedType>(
- cast<AllocaInst>(this), Tracker));
+ Tracker.track(std::make_unique<AllocaSetAllocatedType>(this, Tracker));
cast<llvm::AllocaInst>(Val)->setAllocatedType(Ty);
}
void AllocaInst::setAlignment(Align Align) {
auto &Tracker = Ctx.getTracker();
if (Tracker.isTracking())
- Tracker.track(
- std::make_unique<AllocaSetAlignment>(cast<AllocaInst>(this), Tracker));
+ Tracker.track(std::make_unique<AllocaSetAlignment>(this, Tracker));
cast<llvm::AllocaInst>(Val)->setAlignment(Align);
}
void AllocaInst::setUsedWithInAlloca(bool V) {
auto &Tracker = Ctx.getTracker();
if (Tracker.isTracking())
- Tracker.track(std::make_unique<AllocaSetUsedWithInAlloca>(
- cast<AllocaInst>(this), Tracker));
+ Tracker.track(std::make_unique<AllocaSetUsedWithInAlloca>(this, Tracker));
cast<llvm::AllocaInst>(Val)->setUsedWithInAlloca(V);
}
void AllocaInst::setSwiftError(bool V) {
auto &Tracker = Ctx.getTracker();
if (Tracker.isTracking())
- Tracker.track(
- std::make_unique<AllocaSetSwiftError>(cast<AllocaInst>(this), Tracker));
+ Tracker.track(std::make_unique<AllocaSetSwiftError>(this, Tracker));
cast<llvm::AllocaInst>(Val)->setSwiftError(V);
}
>From 784d198649e50aa03d611b28a596e00b9d467828 Mon Sep 17 00:00:00 2001
From: Vasileios Porpodas <vporpodas at google.com>
Date: Tue, 6 Aug 2024 10:38:42 -0700
Subject: [PATCH 3/3] fixup! fixup! [SandboxIR] Implement AllocaInst
---
llvm/include/llvm/SandboxIR/SandboxIR.h | 9 ++-------
llvm/include/llvm/SandboxIR/Tracker.h | 17 -----------------
llvm/lib/SandboxIR/SandboxIR.cpp | 7 -------
llvm/lib/SandboxIR/Tracker.cpp | 12 ------------
llvm/unittests/SandboxIR/SandboxIRTest.cpp | 7 -------
llvm/unittests/SandboxIR/TrackerTest.cpp | 10 ----------
6 files changed, 2 insertions(+), 60 deletions(-)
diff --git a/llvm/include/llvm/SandboxIR/SandboxIR.h b/llvm/include/llvm/SandboxIR/SandboxIR.h
index 89741894b95ef..1f488adbf5021 100644
--- a/llvm/include/llvm/SandboxIR/SandboxIR.h
+++ b/llvm/include/llvm/SandboxIR/SandboxIR.h
@@ -1404,11 +1404,12 @@ class AllocaInst final : public UnaryInstruction {
return {cast<llvm::Instruction>(Val)};
}
-public:
AllocaInst(llvm::AllocaInst *AI, Context &Ctx)
: UnaryInstruction(ClassID::Alloca, Instruction::Opcode::Alloca, AI,
Ctx) {}
+ friend class Context; // For constructor.
+public:
static AllocaInst *create(Type *Ty, unsigned AddrSpace, BBIterator WhereIt,
BasicBlock *WhereBB, Context &Ctx,
Value *ArraySize = nullptr, const Twine &Name = "");
@@ -1477,12 +1478,6 @@ class AllocaInst final : public UnaryInstruction {
}
/// Specify whether this alloca is used to represent the arguments to a call.
void setUsedWithInAlloca(bool V);
- /// Return true if this alloca is used as a swifterror argument to a call.
- bool isSwiftError() const {
- return cast<llvm::AllocaInst>(Val)->isSwiftError();
- }
- /// Specify whether this alloca is used to represent a swifterror.
- void setSwiftError(bool V);
static bool classof(const Value *From) {
if (auto *I = dyn_cast<Instruction>(From))
diff --git a/llvm/include/llvm/SandboxIR/Tracker.h b/llvm/include/llvm/SandboxIR/Tracker.h
index 3fb52439caef2..af6d015a81518 100644
--- a/llvm/include/llvm/SandboxIR/Tracker.h
+++ b/llvm/include/llvm/SandboxIR/Tracker.h
@@ -307,23 +307,6 @@ class AllocaSetUsedWithInAlloca final : public IRChangeBase {
#endif
};
-class AllocaSetSwiftError final : public IRChangeBase {
- AllocaInst *Alloca;
- bool Orig;
-
-public:
- AllocaSetSwiftError(AllocaInst *Alloca, Tracker &Tracker);
- void revert() final;
- void accept() final {}
-#ifndef NDEBUG
- void dump(raw_ostream &OS) const final {
- dumpCommon(OS);
- OS << "AllocaSetSwiftError";
- }
- LLVM_DUMP_METHOD void dump() const final;
-#endif
-};
-
class CallBrInstSetIndirectDest : public IRChangeBase {
CallBrInst *CallBr;
unsigned Idx;
diff --git a/llvm/lib/SandboxIR/SandboxIR.cpp b/llvm/lib/SandboxIR/SandboxIR.cpp
index e3017b15a7205..ad76698efa709 100644
--- a/llvm/lib/SandboxIR/SandboxIR.cpp
+++ b/llvm/lib/SandboxIR/SandboxIR.cpp
@@ -1259,13 +1259,6 @@ void AllocaInst::setUsedWithInAlloca(bool V) {
cast<llvm::AllocaInst>(Val)->setUsedWithInAlloca(V);
}
-void AllocaInst::setSwiftError(bool V) {
- auto &Tracker = Ctx.getTracker();
- if (Tracker.isTracking())
- Tracker.track(std::make_unique<AllocaSetSwiftError>(this, Tracker));
- cast<llvm::AllocaInst>(Val)->setSwiftError(V);
-}
-
Value *AllocaInst::getArraySize() {
return Ctx.getValue(cast<llvm::AllocaInst>(Val)->getArraySize());
}
diff --git a/llvm/lib/SandboxIR/Tracker.cpp b/llvm/lib/SandboxIR/Tracker.cpp
index 90a9df3c96f31..90c48a3683d83 100644
--- a/llvm/lib/SandboxIR/Tracker.cpp
+++ b/llvm/lib/SandboxIR/Tracker.cpp
@@ -244,18 +244,6 @@ void AllocaSetUsedWithInAlloca::dump() const {
}
#endif // NDEBUG
-AllocaSetSwiftError::AllocaSetSwiftError(AllocaInst *Alloca, Tracker &Tracker)
- : IRChangeBase(Tracker), Alloca(Alloca), Orig(Alloca->isSwiftError()) {}
-
-void AllocaSetSwiftError::revert() { Alloca->setSwiftError(Orig); }
-
-#ifndef NDEBUG
-void AllocaSetSwiftError::dump() const {
- dump(dbgs());
- dbgs() << "\n";
-}
-#endif // NDEBUG
-
CallBrInstSetDefaultDest::CallBrInstSetDefaultDest(CallBrInst *CallBr,
Tracker &Tracker)
: IRChangeBase(Tracker), CallBr(CallBr) {
diff --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
index d53e6d872e628..4b3325d9436ef 100644
--- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp
+++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
@@ -1562,13 +1562,6 @@ define void @foo() {
EXPECT_EQ(AllocaScalar->isUsedWithInAlloca(), NewUsedWithInAlloca);
AllocaScalar->setUsedWithInAlloca(OrigUsedWithInAlloca);
EXPECT_EQ(AllocaScalar->isUsedWithInAlloca(), OrigUsedWithInAlloca);
- // Check isSwiftError(), setSwiftError().
- EXPECT_EQ(AllocaScalar->isSwiftError(), LLVMAllocaScalar->isSwiftError());
- bool OrigIsSwiftError = AllocaScalar->isSwiftError();
- bool NewIsSwiftError = true;
- EXPECT_NE(NewIsSwiftError, OrigIsSwiftError);
- AllocaScalar->setSwiftError(NewIsSwiftError);
- EXPECT_EQ(AllocaScalar->isSwiftError(), NewIsSwiftError);
auto *Ty = Type::getInt32Ty(C);
unsigned AddrSpace = 42;
diff --git a/llvm/unittests/SandboxIR/TrackerTest.cpp b/llvm/unittests/SandboxIR/TrackerTest.cpp
index 12dc6f452504f..36b7c8be3446b 100644
--- a/llvm/unittests/SandboxIR/TrackerTest.cpp
+++ b/llvm/unittests/SandboxIR/TrackerTest.cpp
@@ -687,16 +687,6 @@ define void @foo(i8 %arg) {
EXPECT_EQ(Alloca->isUsedWithInAlloca(), NewWIA);
Ctx.revert();
EXPECT_EQ(Alloca->isUsedWithInAlloca(), OrigWIA);
-
- // Check setSwiftError().
- Ctx.save();
- auto OrigSE = Alloca->isSwiftError();
- bool NewSE = true;
- EXPECT_NE(NewSE, OrigSE);
- Alloca->setSwiftError(NewSE);
- EXPECT_EQ(Alloca->isSwiftError(), NewSE);
- Ctx.revert();
- EXPECT_EQ(Alloca->isSwiftError(), OrigSE);
}
TEST_F(TrackerTest, CallBrSetters) {
More information about the llvm-commits
mailing list