Commit 9699341c authored by Junjie Gu's avatar Junjie Gu Committed by gbsbuild

Added initial code to insert lifetime start to visa to assist visa liveness analysis.

Currently, it is off by default. The initial code only inserts lifetime start for a few
variables. More to come. No Functional change

Change-Id: I72a354db5fbfd8d8044665e3040dd59863e009ee
parent 7bf9d0cd
......@@ -5285,5 +5285,14 @@ void CEncoder::File(std::string& s)
V(vKernel->AppendVISAMiscFileInst(s.c_str()));
}
void CEncoder::Lifetime(VISAVarLifetime StartOrEnd, CVariable* dst)
{
SModifier noMod; // Default is no mod.
noMod.init();
VISA_VectorOpnd* srcOpnd = GetSourceOperand(dst, noMod);
V(vKernel->AppendVISALifetime(StartOrEnd, srcOpnd));
}
}
......@@ -282,6 +282,7 @@ public:
void AddPair(CVariable *Lo, CVariable *Hi, CVariable *L0, CVariable *H0, CVariable *L1, CVariable *H1);
void SubPair(CVariable *Lo, CVariable *Hi, CVariable *L0, CVariable *H0, CVariable *L1, CVariable *H1);
inline void dp4a(CVariable* dst, CVariable* src0, CVariable* src1, CVariable* src2);
void Lifetime(VISAVarLifetime StartOrEnd, CVariable* dst);
// VME
void SendVmeIme(
CVariable* bindingTableIndex,
......
......@@ -417,9 +417,9 @@ bool EmitPass::runOnFunction(llvm::Function &F)
m_currShader->SetCoalescingEngineHelper(m_CE);
}
auto VRA = &getAnalysis<VariableReuseAnalysis>();
m_currShader->SetVariableReuseAnalysis(VRA);
VRA->BeginFunction(&F, numLanes(m_SimdMode));
m_VRA = &getAnalysis<VariableReuseAnalysis>();
m_currShader->SetVariableReuseAnalysis(m_VRA);
m_VRA->BeginFunction(&F, numLanes(m_SimdMode));
if (!m_FGA || m_FGA->isGroupHead(&F))
{
......@@ -474,6 +474,7 @@ bool EmitPass::runOnFunction(llvm::Function &F)
continue;
}
m_destination = nullptr;
if (i != 0)
{
IF_DEBUG_INFO_IF(m_pDebugEmitter, m_pDebugEmitter->BeginEncodingMark();)
......@@ -489,17 +490,18 @@ bool EmitPass::runOnFunction(llvm::Function &F)
PerLaneOffsetVars.clear();
// Variable reuse per-block states.
VariableReuseAnalysis::EnterBlockRAII EnterBlock(VRA, block.bb);
VariableReuseAnalysis::EnterBlockRAII EnterBlock(m_VRA, block.bb);
// go through the list in reverse order
auto I = block.m_dags.rbegin(), E = block.m_dags.rend();
while (I != E)
{
if ((*I).m_root->getDebugLoc())
Instruction* llvmInst = (*I).m_root;
if (llvmInst->getDebugLoc())
{
unsigned int curLineNumber = (*I).m_root->getDebugLoc().getLine();
auto&& srcFile = (*I).m_root->getDebugLoc()->getScope()->getFilename();
auto&& srcDir = (*I).m_root->getDebugLoc()->getScope()->getDirectory();
unsigned int curLineNumber = llvmInst->getDebugLoc().getLine();
auto&& srcFile = llvmInst->getDebugLoc()->getScope()->getFilename();
auto&& srcDir = llvmInst->getDebugLoc()->getScope()->getDirectory();
if (!curSrcFile.equals(srcFile) || !curSrcDir.equals(srcDir))
{
curSrcFile = srcFile;
......@@ -522,27 +524,38 @@ bool EmitPass::runOnFunction(llvm::Function &F)
bool slicing = false;
uint numInstance = DecideInstanceAndSlice(*(block.bb), (*I), slicing);
assert(numInstance == 1 || numInstance == 2);
// m_destination shall be created if this inst has dst.
// It is time to insert lifetime start if it can.
if (m_destination)
{
IF_DEBUG_INFO_IF(m_pDebugEmitter, m_pDebugEmitter->BeginEncodingMark();)
emitLifetimeStart(m_destination, block.bb, llvmInst);
IF_DEBUG_INFO_IF(m_pDebugEmitter, m_pDebugEmitter->EndEncodingMark();)
}
if (slicing && !disableSlicing)
{
IF_DEBUG_INFO_IF(m_pDebugEmitter, m_pDebugEmitter->BeginEncodingMark();)
I = emitInSlice(block, I);
I = emitInSlice(block, I);
IF_DEBUG_INFO_IF(m_pDebugEmitter, m_pDebugEmitter->EndEncodingMark();)
}
if (I != E)
{
auto llvmInst = (*I).m_root;
IF_DEBUG_INFO_IF(m_pDebugEmitter, m_pDebugEmitter->BeginInstruction(llvmInst);)
// before inserting the terminator, initialize constant pool & insert the de-ssa moves
if (isa<BranchInst>((*I).m_root))
{
m_encoder->SetSecondHalf(false);
// insert constant initializations.
InitConstant(block.bb);
// insert the de-ssa movs.
MovPhiSources(block.bb);
}
// before inserting the terminator, initialize constant pool & insert the de-ssa moves
if (isa<BranchInst>(llvmInst))
{
m_encoder->SetSecondHalf(false);
// insert constant initializations.
InitConstant(block.bb);
// insert the de-ssa movs.
MovPhiSources(block.bb);
// Insert lifetime start if there are any
emitLifetimeStartAtEndOfBB(block.bb);
}
// If slicing happens, then recalculate the number of instances.
if (slicing)
......@@ -1071,6 +1084,27 @@ void EmitPass::InitConstant(llvm::BasicBlock *BB)
}
}
void EmitPass::emitLifetimeStartAtEndOfBB(BasicBlock* BB)
{
if (IGC_IS_FLAG_DISABLED(EnableVATemp)) {
return;
}
auto II = m_VRA->m_LifetimeAtEndOfBB.find(BB);
if (II != m_VRA->m_LifetimeAtEndOfBB.end())
{
TinyPtrVector<Value*>& ARVs = II->second;
for (int i = 0, sz = (int)ARVs.size(); i < sz; ++i)
{
Value* RootVal = ARVs[i];
CVariable* Var = GetSymbol(RootVal);
// vISA info inst, no m_encoder->Push() needed.
m_encoder->Lifetime(LIFETIME_START, Var);
}
}
}
std::pair<Value *, Value *> EmitPass::getPairOutput(Value *V) const {
auto I = m_pattern->PairOutputMap.find(V);
assert(I != m_pattern->PairOutputMap.end());
......@@ -7470,6 +7504,29 @@ CVariable *EmitPass::Add(CVariable *Src0, CVariable *Src1, const CVariable *DstP
return Dst;
}
// Insert lifetime start right before instruction I if it is a candidate.
void EmitPass::emitLifetimeStart(CVariable* Var, BasicBlock* BB, Instruction* I)
{
if (IGC_IS_FLAG_DISABLED(EnableVATemp)) {
return;
}
Value* ARV = m_VRA->getAliasRootValue(I);
auto II = m_VRA->m_LifetimeAt1stDefOfBB.find(ARV);
if (II != m_VRA->m_LifetimeAt1stDefOfBB.end())
{
// Insert lifetime start on the root value
// Note that lifetime is a kind of info directive,
// thus no m_encoder->Push() is needed.
CVariable* RootVar = GetSymbol(ARV);
m_encoder->Lifetime(LIFETIME_START, RootVar);
// Once inserted, remove it from map to
// prevent from inserting again.
m_VRA->m_LifetimeAt1stDefOfBB.erase(II);
}
}
void EmitPass::emitGEP(llvm::Instruction* I)
{
GetElementPtrInst &GEP = cast<GetElementPtrInst>(*I);
......
......@@ -159,6 +159,9 @@ public:
// Only remaining GEPs are for scratch in GFX path
void emitGEP(llvm::Instruction* inst);
// Emit lifetime start right before inst V
void emitLifetimeStart(CVariable* Var, llvm::BasicBlock* BB, llvm::Instruction* I);
// set the predicate with current active channels
void emitPredicateFromChannelIP(CVariable* dst, CVariable* alias = NULL);
......@@ -386,6 +389,7 @@ public:
void MovPhiSources(llvm::BasicBlock* bb);
void InitConstant(llvm::BasicBlock *BB);
void emitLifetimeStartAtEndOfBB(llvm::BasicBlock* BB);
std::pair<llvm::Value *, llvm::Value *> getPairOutput(llvm::Value *) const;
......@@ -467,6 +471,7 @@ public:
CEncoder* m_encoder;
const llvm::DataLayout* m_DL;
CoalescingEngine* m_CE;
VariableReuseAnalysis* m_VRA;
ModuleMetaData* m_moduleMD;
bool m_canAbortOnSpill;
......
......@@ -28,10 +28,12 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "Compiler/CISACodeGen/PatternMatchPass.hpp"
#include "Compiler/CISACodeGen/DeSSA.hpp"
#include "Compiler/CISACodeGen/CoalescingEngine.hpp"
#include "Compiler/CISACodeGen/BlockCoalescing.hpp"
#include "common/LLVMWarningsPush.hpp"
#include "llvm/ADT/DenseMap.h"
#include "llvm/IR/Dominators.h"
#include "llvm/ADT/TinyPtrVector.h"
#include <llvm/IR/Function.h>
#include <llvm/IR/Instructions.h>
......@@ -105,11 +107,13 @@ public:
virtual void getAnalysisUsage(llvm::AnalysisUsage &AU) const override {
// AU.addRequired<RegisterEstimator>();
AU.setPreservesAll();
AU.addRequired<llvm::DominatorTreeWrapperPass>();
AU.addRequired<WIAnalysis>();
AU.addRequired<LiveVarsAnalysis>();
AU.addRequired<CodeGenPatternMatch>();
AU.addRequired<DeSSA>();
AU.addRequired<CoalescingEngine>();
AU.addRequired<BlockCoalescing>();
AU.addRequired<CodeGenContextWrapper>();
}
......@@ -175,6 +179,14 @@ public:
int getCongruentClassSize(llvm::Value* V);
bool isSameSizeValue(llvm::Value* V0, llvm::Value* V1);
// getRootValue():
// return dessa root value; if dessa root value
// is null, return itself.
llvm::Value* getRootValue(llvm::Value* V);
// getAliasRootValue()
// return alias root value if it exists, itself otherwise.
llvm::Value *getAliasRootValue(llvm::Value* V);
/// printAlias - print value aliasing info in human readable form
void printAlias(llvm::raw_ostream &OS, const llvm::Function* F = nullptr) const;
/// dumpAalias - dump alias info to dbgs().
......@@ -186,7 +198,16 @@ public:
AliasRootMapTy m_AliasRootMap; // aliasee -> all its aliasers.
// No need to emit code for instructions in this map due to aliasing
llvm::DenseMap <llvm::Instruction*, int > m_HasBecomeNoopInsts;
llvm::DenseMap <llvm::Instruction*, int> m_HasBecomeNoopInsts;
// For emitting livetime start to visa to assist liveness analysis
// 1. m_LifetimeAt1stDefInBB : aliasee -> BB
// Once a first def is encounted, add lifetime start and clear
// this map entry afterwards.
// 2. m_LifetimeAtEndOfBB : BB -> set of values
// Add lifetime start for all values in the set at the end of BB.
llvm::DenseMap<llvm::Value*, llvm::BasicBlock*> m_LifetimeAt1stDefOfBB;
llvm::DenseMap<llvm::BasicBlock*, llvm::TinyPtrVector<llvm::Value*> > m_LifetimeAtEndOfBB;
private:
void reset() {
......@@ -264,14 +285,20 @@ private:
llvm::InsertElementInst* LastIEI,
llvm::SmallVector<SSubVector, 4>& SVs);
void getAllValues(
llvm::SmallVector<llvm::Value*, 8>& AllValues,
llvm::Value* Aliasee);
CodeGenContext* m_pCtx;
WIAnalysis* m_WIA;
LiveVars* m_LV;
DeSSA* m_DeSSA;
CodeGenPatternMatch* m_PatternMatch;
CoalescingEngine* m_coalescingEngine;
llvm::DominatorTree *m_DT;
const llvm::DataLayout* m_DL;
/// Current Function; set on entry to runOnFunction
/// and unset on exit to runOnFunction
llvm::Function* m_F;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment