Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:26

0001 //===- Utils.h --------------------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // Collector for SandboxIR related convenience functions that don't belong in
0010 // other classes.
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   /// \Returns the expected type of \p Value V. For most Values this is
0030   /// equivalent to getType, but for stores returns the stored type, rather
0031   /// than void, and for ReturnInsts returns the returned type.
0032   static Type *getExpectedType(const Value *V) {
0033     if (auto *I = dyn_cast<Instruction>(V)) {
0034       // A Return's value operand can be null if it returns void.
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   /// \Returns the expected Value for this instruction. For most instructions,
0045   /// this is the instruction itself, but for stores returns the stored
0046   /// operand, and for ReturnInstructions returns the returned value.
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   /// \Returns the base Value for load or store instruction \p LSI.
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   /// \Returns the number of bits of \p Ty.
0066   static unsigned getNumBits(Type *Ty, const DataLayout &DL) {
0067     return DL.getTypeSizeInBits(Ty->LLVMTy);
0068   }
0069 
0070   /// \Returns the number of bits required to represent the operands or return
0071   /// value of \p V in \p DL.
0072   static unsigned getNumBits(Value *V, const DataLayout &DL) {
0073     Type *Ty = getExpectedType(V);
0074     return getNumBits(Ty, DL);
0075   }
0076 
0077   /// \Returns the number of bits required to represent the operands or
0078   /// return value of \p I.
0079   static unsigned getNumBits(Instruction *I) {
0080     return I->getDataLayout().getTypeSizeInBits(getExpectedType(I)->LLVMTy);
0081   }
0082 
0083   /// Equivalent to MemoryLocation::getOrNone(I).
0084   static std::optional<llvm::MemoryLocation>
0085   memoryLocationGetOrNone(const Instruction *I) {
0086     return llvm::MemoryLocation::getOrNone(cast<llvm::Instruction>(I->Val));
0087   }
0088 
0089   /// \Returns the gap between the memory locations accessed by \p I0 and
0090   /// \p I1 in bytes.
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, /*StrictCheck=*/false, /*CheckType=*/false);
0107   }
0108 
0109   /// \Returns true if \p I0 accesses a memory location lower than \p I1.
0110   /// Returns false if the difference cannot be determined, if the memory
0111   /// locations are equal, or if I1 accesses a memory location greater than I0.
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   /// Equivalent to BatchAA::getModRefInfo().
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   /// Equivalent to llvm::verifyFunction().
0129   /// \Returns true if the IR is broken.
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 } // namespace llvm::sandboxir
0137 
0138 #endif // LLVM_SANDBOXIR_UTILS_H