File indexing completed on 2026-05-10 08:44:26
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef LLVM_SANDBOXIR_UTILS_H
0013 #define LLVM_SANDBOXIR_UTILS_H
0014
0015 #include "llvm/Analysis/AliasAnalysis.h"
0016 #include "llvm/Analysis/LoopAccessAnalysis.h"
0017 #include "llvm/Analysis/MemoryLocation.h"
0018 #include "llvm/Analysis/ScalarEvolution.h"
0019 #include "llvm/Analysis/ValueTracking.h"
0020 #include "llvm/IR/Verifier.h"
0021 #include "llvm/SandboxIR/Function.h"
0022 #include "llvm/SandboxIR/Instruction.h"
0023 #include <optional>
0024
0025 namespace llvm::sandboxir {
0026
0027 class Utils {
0028 public:
0029
0030
0031
0032 static Type *getExpectedType(const Value *V) {
0033 if (auto *I = dyn_cast<Instruction>(V)) {
0034
0035 if (auto *RI = dyn_cast<ReturnInst>(I)) {
0036 if (RI->getReturnValue() == nullptr)
0037 return RI->getType();
0038 }
0039 return getExpectedValue(I)->getType();
0040 }
0041 return V->getType();
0042 }
0043
0044
0045
0046
0047 static Value *getExpectedValue(const Instruction *I) {
0048 if (auto *SI = dyn_cast<StoreInst>(I))
0049 return SI->getValueOperand();
0050 if (auto *RI = dyn_cast<ReturnInst>(I))
0051 return RI->getReturnValue();
0052 return const_cast<Instruction *>(I);
0053 }
0054
0055
0056 template <typename LoadOrStoreT>
0057 static Value *getMemInstructionBase(const LoadOrStoreT *LSI) {
0058 static_assert(std::is_same_v<LoadOrStoreT, LoadInst> ||
0059 std::is_same_v<LoadOrStoreT, StoreInst>,
0060 "Expected sandboxir::Load or sandboxir::Store!");
0061 return LSI->Ctx.getOrCreateValue(
0062 getUnderlyingObject(LSI->getPointerOperand()->Val));
0063 }
0064
0065
0066 static unsigned getNumBits(Type *Ty, const DataLayout &DL) {
0067 return DL.getTypeSizeInBits(Ty->LLVMTy);
0068 }
0069
0070
0071
0072 static unsigned getNumBits(Value *V, const DataLayout &DL) {
0073 Type *Ty = getExpectedType(V);
0074 return getNumBits(Ty, DL);
0075 }
0076
0077
0078
0079 static unsigned getNumBits(Instruction *I) {
0080 return I->getDataLayout().getTypeSizeInBits(getExpectedType(I)->LLVMTy);
0081 }
0082
0083
0084 static std::optional<llvm::MemoryLocation>
0085 memoryLocationGetOrNone(const Instruction *I) {
0086 return llvm::MemoryLocation::getOrNone(cast<llvm::Instruction>(I->Val));
0087 }
0088
0089
0090
0091 template <typename LoadOrStoreT>
0092 static std::optional<int> getPointerDiffInBytes(LoadOrStoreT *I0,
0093 LoadOrStoreT *I1,
0094 ScalarEvolution &SE) {
0095 static_assert(std::is_same_v<LoadOrStoreT, LoadInst> ||
0096 std::is_same_v<LoadOrStoreT, StoreInst>,
0097 "Expected sandboxir::Load or sandboxir::Store!");
0098 llvm::Value *Opnd0 = I0->getPointerOperand()->Val;
0099 llvm::Value *Opnd1 = I1->getPointerOperand()->Val;
0100 llvm::Value *Ptr0 = getUnderlyingObject(Opnd0);
0101 llvm::Value *Ptr1 = getUnderlyingObject(Opnd1);
0102 if (Ptr0 != Ptr1)
0103 return false;
0104 llvm::Type *ElemTy = llvm::Type::getInt8Ty(SE.getContext());
0105 return getPointersDiff(ElemTy, Opnd0, ElemTy, Opnd1, I0->getDataLayout(),
0106 SE, false, false);
0107 }
0108
0109
0110
0111
0112 template <typename LoadOrStoreT>
0113 static bool atLowerAddress(LoadOrStoreT *I0, LoadOrStoreT *I1,
0114 ScalarEvolution &SE) {
0115 auto Diff = getPointerDiffInBytes(I0, I1, SE);
0116 if (!Diff)
0117 return false;
0118 return *Diff > 0;
0119 }
0120
0121
0122 static ModRefInfo
0123 aliasAnalysisGetModRefInfo(BatchAAResults &BatchAA, const Instruction *I,
0124 const std::optional<MemoryLocation> &OptLoc) {
0125 return BatchAA.getModRefInfo(cast<llvm::Instruction>(I->Val), OptLoc);
0126 }
0127
0128
0129
0130 static bool verifyFunction(const Function *F, raw_ostream &OS) {
0131 const auto &LLVMF = *cast<llvm::Function>(F->Val);
0132 return llvm::verifyFunction(LLVMF, &OS);
0133 }
0134 };
0135
0136 }
0137
0138 #endif