File: LivenessAnalysis.hpp

package info (click to toggle)
intel-graphics-compiler 1.0.12504.6-1%2Bdeb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 83,912 kB
  • sloc: cpp: 910,147; lisp: 202,655; ansic: 15,197; python: 4,025; yacc: 2,241; lex: 1,570; pascal: 244; sh: 104; makefile: 25
file content (163 lines) | stat: -rw-r--r-- 5,501 bytes parent folder | download
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
/*========================== begin_copyright_notice ============================

Copyright (C) 2017-2021 Intel Corporation

SPDX-License-Identifier: MIT

============================= end_copyright_notice ===========================*/

#pragma once
#include "Compiler/CISACodeGen/CISACodeGen.h"
#include "Compiler/CISACodeGen/LiveVars.hpp"
#include "Compiler/IGCPassSupport.h"
#include "common/LLVMWarningsPush.hpp"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SparseBitVector.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Value.h"
#include <llvm/Support/Allocator.h>
#include "common/LLVMWarningsPop.hpp"
#include "Probe/Assertion.h"

namespace IGC
{
    typedef llvm::SparseBitVector<>                         SBitVector;
    typedef llvm::SmallVector<llvm::Value*, 4>              ValueVec;
    typedef llvm::DenseMap<llvm::BasicBlock*, SBitVector>   BBLiveInMap;
    typedef llvm::DenseMap<llvm::Value*, ValueVec>          ValueToValueVecMap;
    typedef llvm::DenseMap<llvm::Value*, int>               ValueToIntMap;
    typedef llvm::SmallVector<llvm::Value*, 32>             IntToValueVector;

    //  LivenessAnalysis compute liveness information based on LiveVars.
    //  It has three kinds of information: IN set, defInst, killInsts
    //     IN:  live-in set, one for each BB (BBLiveInMap)
    //     defInst: def instruction. Since it is a SSA, Value itself
    //              denotes that.
    //     killInsts: Given an inst, killInsts has all values that have
    //              their last uses at this inst (ValueToValueSetMap).
    class LivenessAnalysis : public llvm::FunctionPass {
    public:

        static char ID; // Pass identification, replacement for typeid

        LivenessAnalysis() :
            llvm::FunctionPass(ID),
            m_LV(nullptr),
            m_F(nullptr),
            m_WIA(nullptr)
        {
            initializeLivenessAnalysisPass(*llvm::PassRegistry::getPassRegistry());
        }

        ~LivenessAnalysis();

        // Liveness is computed on demand, by explicitly calling calculate().
        // runOnFunction does not calculate it!
        //
        // This gives the liveness users' the full control, so that the users
        // will only calculate liveness when it is needed. Doing so will save
        // compiling time.
        //
        // Note that runOnFunction() will set up ValueIds map as PreRAScheduler
        // uses it directly, even though Liveness is not computed.
        bool runOnFunction(llvm::Function& F) override;

        // Entry to compute Liveness
        void calculate(llvm::Function* F);

        llvm::StringRef getPassName() const override { return "LivenessAnalysis"; }

        void getAnalysisUsage(llvm::AnalysisUsage& AU) const override
        {
            //AU.addRequired<LiveVarsAnalysis>();
            AU.setPreservesAll();
        }

        // Return the distance of instruction within BB (start from 0).
        // (See LiveVars for the detail of distance)
        uint32_t getDistance(llvm::Instruction* I)
        {
            return m_LV->getDistance(I);
        }

        LiveVars* getLiveVars() { return m_LV; }

        llvm::Value* getValueFromBitId(int BitId)
        {
            llvm::Value* V = nullptr;
            if (BitId < (int)IdValues.size())
            {
                V = IdValues[BitId];
            }
            IGC_ASSERT_MESSAGE(nullptr != V, "Invalid bit id found!");
            return V;
        }

        // Return true if instruction I has the last use of V.
        bool isInstLastUseOfValue(llvm::Value* V, llvm::Instruction* I);
        // For A and B that are in the same BB, check if A appears before B.
        bool isBefore(llvm::Instruction* A, llvm::Instruction* B);

        // Return true if V is uniform
        bool isUniform(llvm::Value* V) const
        {
            return m_WIA && m_WIA->isUniform(V);
        }

        bool isCandidateValue(llvm::Value* V)
        {
            return ValueIds.count(V) > 0;
        }

        uint32_t getNumValues() const { return IdValues.size(); }

        // release all memory.
        void clear();

        virtual void releaseMemory() override {
            clear();
        }

    private:

        LiveVars* m_LV;
        llvm::Function* m_F;
        WIAnalysis* m_WIA;  // Optional

        void initValueIds();
        void setLiveIn(llvm::BasicBlock* BB, llvm::Value* V);
        void setLiveIn(llvm::BasicBlock* BB, int ValueID);
        void setKillInsts(llvm::Value* V, llvm::Instruction* kill);

    public:
        // Value --> its ID  & ID --> Value
        ValueToIntMap    ValueIds;
        IntToValueVector IdValues;

        // IN set, one for each BB
        BBLiveInMap  BBLiveIns;

        // Instruction (first, as value) and all values whose last uses are
        // at this instruction.
        ValueToValueVecMap KillInsts;

        /// print - Convert to human readable form
        void print(llvm::raw_ostream& OS);

        /// print_livein : print live in set for a BB
        void print_livein(llvm::raw_ostream& OS, llvm::BasicBlock* BB);

#if defined( _DEBUG )
        /// dump - Dump the liveness info to dbgs(), used in debugger.
        void dump();
        void dump_livein();
        void dump_livein(llvm::BasicBlock* BB);
#endif

        // May be placed somewhere else
        static std::string getllvmValueName(llvm::Value* V);
    };
}