Skip to content

[SandboxIR] Implement VAArgInst #106247

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions llvm/include/llvm/SandboxIR/SandboxIR.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ class ConstantInt;
class Context;
class Function;
class Instruction;
class VAArgInst;
class FreezeInst;
class FenceInst;
class SelectInst;
Expand Down Expand Up @@ -255,6 +256,7 @@ class Value {
friend class Context; // For getting `Val`.
friend class User; // For getting `Val`.
friend class Use; // For getting `Val`.
friend class VAArgInst; // For getting `Val`.
friend class FreezeInst; // For getting `Val`.
friend class FenceInst; // For getting `Val`.
friend class SelectInst; // For getting `Val`.
Expand Down Expand Up @@ -688,6 +690,7 @@ class Instruction : public sandboxir::User {
/// A SandboxIR Instruction may map to multiple LLVM IR Instruction. This
/// returns its topmost LLVM IR instruction.
llvm::Instruction *getTopmostLLVMInstruction() const;
friend class VAArgInst; // For getTopmostLLVMInstruction().
friend class FreezeInst; // For getTopmostLLVMInstruction().
friend class FenceInst; // For getTopmostLLVMInstruction().
friend class SelectInst; // For getTopmostLLVMInstruction().
Expand Down Expand Up @@ -1543,6 +1546,27 @@ class UnaryInstruction
}
};

class VAArgInst : public UnaryInstruction {
VAArgInst(llvm::VAArgInst *FI, Context &Ctx)
: UnaryInstruction(ClassID::VAArg, Opcode::VAArg, FI, Ctx) {}
friend Context; // For constructor;

public:
static VAArgInst *create(Value *List, Type *Ty, BBIterator WhereIt,
BasicBlock *WhereBB, Context &Ctx,
const Twine &Name = "");
Value *getPointerOperand();
const Value *getPointerOperand() const {
return const_cast<VAArgInst *>(this)->getPointerOperand();
}
static unsigned getPointerOperandIndex() {
return llvm::VAArgInst::getPointerOperandIndex();
}
static bool classof(const Value *From) {
return From->getSubclassID() == ClassID::VAArg;
}
};

class FreezeInst : public UnaryInstruction {
FreezeInst(llvm::FreezeInst *FI, Context &Ctx)
: UnaryInstruction(ClassID::Freeze, Opcode::Freeze, FI, Ctx) {}
Expand Down Expand Up @@ -3006,6 +3030,8 @@ class Context {
IRBuilder<ConstantFolder> LLVMIRBuilder;
auto &getLLVMIRBuilder() { return LLVMIRBuilder; }

VAArgInst *createVAArgInst(llvm::VAArgInst *SI);
friend VAArgInst; // For createVAArgInst()
FreezeInst *createFreezeInst(llvm::FreezeInst *SI);
friend FreezeInst; // For createFreezeInst()
FenceInst *createFenceInst(llvm::FenceInst *SI);
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/SandboxIR/SandboxIRValues.def
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ DEF_USER(ConstantInt, ConstantInt)
DEF_INSTR(Opaque, OP(Opaque), OpaqueInst)
DEF_INSTR(ExtractElement, OP(ExtractElement), ExtractElementInst)
DEF_INSTR(InsertElement, OP(InsertElement), InsertElementInst)
DEF_INSTR(VAArg, OP(VAArg), VAArgInst)
DEF_INSTR(Freeze, OP(Freeze), FreezeInst)
DEF_INSTR(Fence, OP(Fence), FenceInst)
DEF_INSTR(ShuffleVector, OP(ShuffleVector), ShuffleVectorInst)
Expand Down
26 changes: 26 additions & 0 deletions llvm/lib/SandboxIR/SandboxIR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,22 @@ void Instruction::dumpOS(raw_ostream &OS) const {
}
#endif // NDEBUG

VAArgInst *VAArgInst::create(Value *List, Type *Ty, BBIterator WhereIt,
BasicBlock *WhereBB, Context &Ctx,
const Twine &Name) {
auto &Builder = Ctx.getLLVMIRBuilder();
if (WhereIt != WhereBB->end())
Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
else
Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
auto *LLVMI = cast<llvm::VAArgInst>(Builder.CreateVAArg(List->Val, Ty, Name));
return Ctx.createVAArgInst(LLVMI);
}

Value *VAArgInst::getPointerOperand() {
return Ctx.getValue(cast<llvm::VAArgInst>(Val)->getPointerOperand());
}

FreezeInst *FreezeInst::create(Value *V, BBIterator WhereIt,
BasicBlock *WhereBB, Context &Ctx,
const Twine &Name) {
Expand Down Expand Up @@ -2251,6 +2267,11 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
assert(isa<llvm::Instruction>(LLVMV) && "Expected Instruction");

switch (cast<llvm::Instruction>(LLVMV)->getOpcode()) {
case llvm::Instruction::VAArg: {
auto *LLVMVAArg = cast<llvm::VAArgInst>(LLVMV);
It->second = std::unique_ptr<VAArgInst>(new VAArgInst(LLVMVAArg, *this));
return It->second.get();
}
case llvm::Instruction::Freeze: {
auto *LLVMFreeze = cast<llvm::FreezeInst>(LLVMV);
It->second = std::unique_ptr<FreezeInst>(new FreezeInst(LLVMFreeze, *this));
Expand Down Expand Up @@ -2465,6 +2486,11 @@ BasicBlock *Context::createBasicBlock(llvm::BasicBlock *LLVMBB) {
return BB;
}

VAArgInst *Context::createVAArgInst(llvm::VAArgInst *SI) {
auto NewPtr = std::unique_ptr<VAArgInst>(new VAArgInst(SI, *this));
return cast<VAArgInst>(registerValue(std::move(NewPtr)));
}

FreezeInst *Context::createFreezeInst(llvm::FreezeInst *SI) {
auto NewPtr = std::unique_ptr<FreezeInst>(new FreezeInst(SI, *this));
return cast<FreezeInst>(registerValue(std::move(NewPtr)));
Expand Down
33 changes: 33 additions & 0 deletions llvm/unittests/SandboxIR/SandboxIRTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,39 @@ define void @foo(i8 %v1) {
EXPECT_EQ(I0->getNextNode(), Ret);
}

TEST_F(SandboxIRTest, VAArgInst) {
parseIR(C, R"IR(
define void @foo(ptr %va) {
%va_arg = va_arg ptr %va, i32
ret void
}
)IR");
llvm::Function *LLVMF = &*M->getFunction("foo");

sandboxir::Context Ctx(C);
sandboxir::Function *F = Ctx.createFunction(LLVMF);
auto *Arg = F->getArg(0);
auto *BB = &*F->begin();
auto It = BB->begin();
auto *VA = cast<sandboxir::VAArgInst>(&*It++);
auto *Ret = cast<sandboxir::ReturnInst>(&*It++);

// Check getPointerOperand().
EXPECT_EQ(VA->getPointerOperand(), Arg);
// Check getPOinterOperandIndex().
EXPECT_EQ(sandboxir::VAArgInst::getPointerOperandIndex(),
llvm::VAArgInst::getPointerOperandIndex());
// Check create().
auto *NewVATy = Type::getInt8Ty(C);
auto *NewVA = sandboxir::VAArgInst::create(Arg, NewVATy, Ret->getIterator(),
Ret->getParent(), Ctx, "NewVA");
EXPECT_EQ(NewVA->getNextNode(), Ret);
EXPECT_EQ(NewVA->getType(), NewVATy);
#ifndef NDEBUG
EXPECT_EQ(NewVA->getName(), "NewVA");
#endif // NDEBUG
}

TEST_F(SandboxIRTest, FreezeInst) {
parseIR(C, R"IR(
define void @foo(i8 %arg) {
Expand Down
Loading