Sandbox IR is an IR layer on top of LLVM IR that allows you to save/restore its state.
The Sandbox IR API is designed to feel like LLVM, replicating many common API classes and functions to mirror the LLVM API. The class hierarchy is similar (but in the llvm::sandboxir
namespace). For example here is a small part of it:
namespace sandboxir { Value / \ User BasicBlock ... / \ Instruction Constant / ... }
Each LLVM IR Value maps to a single Sandbox IR Value. The reverse is also true in most cases, except for Sandbox IR Instructions that map to more than one LLVM IR Instruction. Such instructions can be defined in extensions of the base Sandbox IR.
Forward mapping: Sandbox IR Value -> LLVM IR Value Each Sandbox IR Value contains an llvm::Value *Val
member variable that points to the corresponding LLVM IR Value.
Reverse mapping: LLVM IR Value -> Sandbox IR Value This mapping is stored in sandboxir::Context::LLVMValueToValue
.
For example sandboxir::User::getOperand(OpIdx)
for a sandboxir::User *U
works as follows:
llvm::User *LLVMU = U->Val
.llvm::Value *LLVMOp = LLVMU->getOperand(OpIdx)
LLVMOp
by querying the map in the Sandbox IR context: retrun Ctx.getValue(LLVMOp)
.Sandbox IR is designed to rely on LLVM IR for its state. So any change made to Sandbox IR objects directly updates the corresponding LLVM IR.
This has the following benefits:
llvm::Instruction
s to cost modeling APIs.Sandbox IR API functions that modify the IR state call the corresponding LLVM IR function that modifies the LLVM IR's state. For example, for sandboxir::User::setOperand(OpIdx, sandboxir::Value *Op)
:
llvm::User *LLVMU = cast<llvm::User>(Val)
llvm::Value *LLVMOp = Op->Val
LLVMU
's operand: `LLVMU->setOperand(OpIdx, LLVMOp)