1 /*========================== begin_copyright_notice ============================ 2 3 Copyright (C) 2017-2021 Intel Corporation 4 5 SPDX-License-Identifier: MIT 6 7 ============================= end_copyright_notice ===========================*/ 8 9 #pragma once 10 11 #include "common/LLVMWarningsPush.hpp" 12 #include <llvm/Pass.h> 13 #include <llvm/ADT/MapVector.h> 14 #include <llvm/IR/DataLayout.h> 15 #include <llvm/IR/InstVisitor.h> 16 #include "common/LLVMWarningsPop.hpp" 17 18 namespace IGC 19 { 20 21 /// @brief This pass correctly sets the alignment of all loads 22 /// and stores according to OpenCL rules. 23 /// It perform a data-flow analysis to keep track of the highest power 24 /// of 2 that divides a value. 25 /// This tracking is performed for integers and for pointers, and is 26 /// based on the assumption that global variables and kernel arguments 27 /// are always aligned on their data type. 28 /// The result is an underapproximation of the actual alignment, so it 29 /// is always safe. 30 class AlignmentAnalysis : public llvm::FunctionPass, public llvm::InstVisitor<AlignmentAnalysis, unsigned int> 31 { 32 public: 33 // Pass identification, replacement for typeid 34 static char ID; 35 36 /// @brief Constructor 37 AlignmentAnalysis(); 38 39 /// @brief Destructor ~AlignmentAnalysis()40 ~AlignmentAnalysis() {} 41 42 /// @brief Provides name of pass getPassName() const43 virtual llvm::StringRef getPassName() const override 44 { 45 return "AlignmentAnalysisPass"; 46 } 47 getAnalysisUsage(llvm::AnalysisUsage & AU) const48 virtual void getAnalysisUsage(llvm::AnalysisUsage& AU) const override 49 { 50 AU.setPreservesCFG(); 51 } 52 53 /// @brief Main entry point. 54 virtual bool runOnFunction(llvm::Function& F) override; 55 56 // @ brief Instruction visitors 57 unsigned int visitInstruction(llvm::Instruction& I); 58 unsigned int visitAllocaInst(llvm::AllocaInst& I); 59 unsigned int visitIntToPtrInst(llvm::IntToPtrInst& I); 60 unsigned int visitPtrToIntInst(llvm::PtrToIntInst& I); 61 unsigned int visitSelectInst(llvm::SelectInst& I); 62 unsigned int visitGetElementPtrInst(llvm::GetElementPtrInst& I); 63 unsigned int visitPHINode(llvm::PHINode& I); 64 unsigned int visitBitCastInst(llvm::BitCastInst& I); 65 unsigned int visitAdd(llvm::BinaryOperator& I); 66 unsigned int visitMul(llvm::BinaryOperator& I); 67 unsigned int visitShl(llvm::BinaryOperator& I); 68 unsigned int visitAnd(llvm::BinaryOperator& I); 69 unsigned int visitTruncInst(llvm::TruncInst& I); 70 unsigned int visitZExtInst(llvm::ZExtInst& I); 71 unsigned int visitSExtInst(llvm::SExtInst& I); 72 unsigned int visitCallInst(llvm::CallInst& I); 73 74 void SetInstAlignment(llvm::Instruction& I); 75 void SetInstAlignment(llvm::LoadInst& I); 76 void SetInstAlignment(llvm::StoreInst& I); 77 void SetInstAlignment(llvm::MemSetInst& I); 78 void SetInstAlignment(llvm::MemCpyInst& I); 79 void SetInstAlignment(llvm::MemMoveInst& I); 80 81 protected: 82 /// @breif Evaluates the alignment of I based on its operands. 83 /// For Load and Store instructions, also sets the alignment 84 /// of the operation itself. 85 /// @param I The instruction to process 86 bool processInstruction(llvm::Instruction* I); 87 88 /// @brief Returns the alignment for V, if it is known. 89 /// Otherwise, returns the maximum alignment. 90 /// @param V the value the alignment of which we're interested in 91 unsigned int getAlignValue(llvm::Value* V) const; 92 93 /// @brief Returns the alignment of a constant integer. 94 /// This is normally 1 << ctz(C) (the highest power of 2 that divides C), 95 /// except when C is 0, when it is the max alignment 96 unsigned int getConstantAlignment(uint64_t C) const; 97 98 /// @brief This map stores the known alignment of every value. 99 llvm::MapVector<llvm::Value*, unsigned int> m_alignmentMap; 100 101 static const unsigned int MinimumAlignment = 1; 102 103 const llvm::DataLayout* m_DL; 104 }; 105 106 } // namespace IGC 107