1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
|
/*========================== begin_copyright_notice ============================
Copyright (C) 2017-2021 Intel Corporation
SPDX-License-Identifier: MIT
============================= end_copyright_notice ===========================*/
/*========================== begin_copyright_notice ============================
This file is distributed under the University of Illinois Open Source License.
See LICENSE.TXT for details.
============================= end_copyright_notice ===========================*/
//===------------ LiveVars.h - Live Variable Analysis -----------*- C++ -*-===//
//
// Intel extension to LLVM core
//
//===----------------------------------------------------------------------===//
//
// This file implements the LiveVariables analysis pass. It originates from
// the same function in llvm3.0/codegen, however works on llvm-ir instead of
// the code-gen-level ir.
//
// This class computes live variables using a sparse implementation based on
// the llvm-ir SSA form. This class uses the dominance properties of SSA form
// to efficiently compute live variables for virtual registers. Also Note that
// there is no physical register at llvm-ir level.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_IEXT_LIVEVARS_H
#define LLVM_IEXT_LIVEVARS_H
#include "Compiler/CISACodeGen/WIAnalysis.hpp"
#include "common/LLVMWarningsPush.hpp"
#include <llvm/Pass.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/Instruction.h>
#include <llvm/IR/Instructions.h>
#include <llvm/IR/CFG.h>
#include <llvm/ADT/DenseMap.h>
#include <llvm/ADT/SmallSet.h>
#include <llvm/ADT/SmallVector.h>
#include <llvm/Support/Allocator.h>
#include "common/LLVMWarningsPop.hpp"
#include <map>
namespace IGC
{
class LiveVars {
public:
// forward declaration
struct LVInfo;
typedef llvm::DenseMap<llvm::Value*, LVInfo*> LVInfoMap;
typedef LVInfoMap::iterator iterator;
typedef LVInfoMap::const_iterator const_iterator;
LiveVars() {}
~LiveVars();
/// LVInfo - This represents the regions where a virtual register is live in
/// the program. We represent this with three different pieces of
/// information: the set of blocks in which the instruction is live
/// throughout, the set of blocks in which the instruction is actually used,
/// and the set of non-phi instructions that are the last users of the value.
///
/// In the common case where a value is defined and killed in the same block,
/// There is one killing instruction, and AliveBlocks is empty.
///
/// Otherwise, the value is live out of the block. If the value is live
/// throughout any blocks, these blocks are listed in AliveBlocks. Blocks
/// where the liveness range ends are not included in AliveBlocks, instead
/// being captured by the Kills set. In these blocks, the value is live into
/// the block (unless the value is defined and killed in the same block) and
/// lives until the specified instruction. Note that there cannot ever be a
/// value whose Kills set contains two instructions from the same basic block.
///
/// PHI nodes complicate things a bit. If a PHI node is the last user of a
/// value in one of its predecessor blocks, it is not listed in the kills set,
/// but does include the predecessor block in the AliveBlocks set (unless that
/// block also defines the value). This leads to the (perfectly sensical)
/// situation where a value is defined in a block, and the last use is a phi
/// node in the successor. In this case, AliveBlocks is empty (the value is
/// not live across any blocks) and Kills is empty (phi nodes are not
/// included). This is sensical because the value must be live to the end of
/// the block, but is not live in any successor blocks.
struct LVInfo {
/// AliveBlocks - Set of blocks in which this value is alive completely
/// through.
llvm::SmallPtrSet<llvm::BasicBlock*, 16> AliveBlocks;
///std::set<llvm::BasicBlock*> AliveBlocks;
/// NumUses - Number of uses of this register across the entire function.
///
unsigned NumUses;
/// Kills - List of llvm::Instruction's which are the last use of this
/// virtual register (kill it) in their basic block.
///
std::vector<llvm::Instruction*> Kills;
bool uniform;
LVInfo() : NumUses(0), uniform(false) {}
/// removeKill - Delete a kill corresponding to the specified
/// instruction. Returns true if there was a kill
/// corresponding to this instruction, false otherwise.
bool removeKill(llvm::Instruction* MI) {
std::vector<llvm::Instruction*>::iterator
I = std::find(Kills.begin(), Kills.end(), MI);
if (I == Kills.end())
return false;
Kills.erase(I);
return true;
}
/// findKill - Find a kill instruction in basic block. Return NULL if none is found.
llvm::Instruction* findKill(const llvm::BasicBlock* MBB) const;
/// isLiveIn - Is Reg live in to MBB? This means that Reg is live through
/// MBB, or it is killed in BB. If Reg is only used by PHI instructions in
/// MBB, it is not considered live in.
bool isLiveIn(const llvm::BasicBlock& MBB, llvm::Value* LV);
void print(llvm::raw_ostream& OS) const;
}; // end of LVInfo
private:
/// VirtRegInfo - This list is a mapping from a llvm::value to
/// its liveness information.
///
LVInfoMap VirtRegInfo;
private: // Intermediate data structures
llvm::Function* MF;
WIAnalysis* WIA;
llvm::SpecificBumpPtrAllocator<LVInfo> Allocator;
// For each basic-block, we have a vector of phi-uses if there are phi-insts
// in a successor-block
llvm::DenseMap<llvm::BasicBlock*, llvm::SmallVector<llvm::Value*, 4>> PHIVarInfo;
// DistanceMap - Keep track the distance of an Instr from the start of the
// current basic block.
llvm::DenseMap<llvm::Instruction*, unsigned> DistanceMap;
/// analyzePHINodes - Gather information about the PHI nodes in here. In
/// particular, we want to map the variable information of a virtual
/// register which is used in a PHI node. We map that to the BB the vreg
/// is coming from.
void analyzePHINodes(const llvm::Function& MF);
/// Initialize DistanceMap
void initDistance(llvm::Function& F);
public:
/// Can be called to release memory when the object won't be used anymore.
void releaseMemory();
/// Pre-allocate memory for llvm::DenseMap to avoid many small allocations
void preAllocMemory(llvm::Function& F);
/// getLVInfo - Return the LVInfo structure for the specified VIRTUAL
/// register.
LVInfo& getLVInfo(llvm::Value* LV);
/// Get the relative location of an instruction within a basic block
unsigned getDistance(const llvm::Instruction* MI) {
return DistanceMap[(llvm::Instruction*)MI];
}
void MarkVirtRegAliveInBlock(LVInfo& VRInfo, llvm::BasicBlock* DefBlock,
llvm::BasicBlock* BB);
void MarkVirtRegAliveInBlock(LVInfo& VRInfo, llvm::BasicBlock* DefBlock,
llvm::BasicBlock* BB,
std::vector<llvm::BasicBlock*>& WorkList);
// ScanBBTopDown: true if instructions of a BB is scanned top-down
void HandleVirtRegUse(llvm::Value* LV, llvm::BasicBlock* MBB, llvm::Instruction* MI,
bool ScanAllUses = false, bool ScanBBTopDown = false);
void HandleVirtRegDef(llvm::Instruction* MI);
void ComputeLiveness(llvm::Function*, WIAnalysis*);
// Calculate liveness info for all live variables
// (same as runOnMachineFunction() of llvm LiveVariables pass
void Calculate(llvm::Function* F, WIAnalysis* WIA = nullptr);
iterator begin() { return VirtRegInfo.begin(); }
const_iterator begin() const { return VirtRegInfo.begin(); }
iterator end() { return VirtRegInfo.end(); }
const_iterator end() const { return VirtRegInfo.end(); }
bool isLiveIn(llvm::Value* LV, const llvm::BasicBlock& MBB) {
return getLVInfo(LV).isLiveIn(MBB, LV);
}
bool isLiveAt(llvm::Value* LV, llvm::Instruction* MI);
/// isLiveOut - Determine if Reg is live out from MBB, when not considering
/// PHI nodes. This means that Reg is either killed by a successor block or
/// passed through one.
bool isLiveOut(llvm::Value* LV, const llvm::BasicBlock& MBB);
/// Merge LVInfo of "fromV" into V's LVInfo (ignore the def of "fromV")
/// Note that this is used after LVInfo has been constructed already.
void mergeUseFrom(llvm::Value* V, llvm::Value* fromV);
/// If two values' live ranges overlap, return true.
bool hasInterference(llvm::Value* V0, llvm::Value* V1);
/// print - Convert to human readable form
void print(llvm::raw_ostream& OS, const llvm::Module* = nullptr) const;
/// dump - Dump the LVInfo to dbgs().
void dump() const;
#if defined( _DEBUG )
// for debugging
llvm::DenseMap<llvm::BasicBlock*, int> BBIds;
llvm::DenseMap<int, llvm::BasicBlock*> IdToBBs;
void setupBBIds(llvm::Function* F);
void dump(llvm::Function* F);
void dump(int BBId);
#endif
};
/// \brief Analysis pass which computes a LiveVars.
class LiveVarsAnalysis : public llvm::FunctionPass {
LiveVars LV;
public:
static char ID;
LiveVarsAnalysis();
LiveVars& getLiveVars() { return LV; }
const LiveVars& getLiveVars() const { return LV; }
bool runOnFunction(llvm::Function& F) override;
void getAnalysisUsage(llvm::AnalysisUsage& AU) const override {
AU.addRequired<MetaDataUtilsWrapper>();
AU.setPreservesAll();
}
void releaseMemory() override { LV.releaseMemory(); }
};
} // End CISA namespace
#endif
|