File: GenXModule.h

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 (145 lines) | stat: -rw-r--r-- 5,013 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
/*========================== begin_copyright_notice ============================

Copyright (C) 2017-2021 Intel Corporation

SPDX-License-Identifier: MIT

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

//
/// GenXModule
/// ----------
///
/// GenXModule is a module pass whose purpose is to store information
/// about the module being written, such as the built kernels and functions.
///
/// A vISA kernel or function can call a *subroutine*, which can
/// then call further subroutines. All called subroutines are considered part of
/// the kernel or function, which means that a subroutine used by two different
/// kernels needs to have a copy in each. The two copies may be treated
/// differently by the backend passes, so there does actually need to be two
/// copies of the subroutine in the LLVM IR in the backend, one called by each
/// kernel.
///
/// The GenXModule pass performs any necessary copying of subroutines, and
/// populates FunctionGroupAnalysis such that each kernel and its subroutines
/// make one FunctionGroup.
///
/// Subsequent passes are mostly FunctionGroupPasses, so they process one
/// FunctionGroup at a time.
///
/// GenXModule is also an analysis, preserved through subsequent passes to
/// GenXFinalizer at the end, that is used to store each written vISA kernel.
///
/// **IR restriction**: After this pass, the lead function in a FunctionGroup is
/// a kernel (or function in the vISA sense), and other functions in the same
/// FunctionGroup are its subroutines.  A (non-intrinsic) call must be to a
/// function in the same FunctionGroup, and not the lead function.
///
//===----------------------------------------------------------------------===//
#ifndef GENXMODULE_H
#define GENXMODULE_H

#include "GenX.h"
#include "GenXBaling.h"
#include "GenXDebugInfo.h"

#include "vc/Support/BackendConfig.h"

#include "llvm/ADT/Twine.h"
#include "llvm/Pass.h"
#include "llvm/PassRegistry.h"

#include <inc/common/sku_wa.h>

#include <map>
#include <string>
#include <vector>

#include "Probe/Assertion.h"

class VISABuilder;
class VISAKernel;

namespace llvm {
  class GenXSubtarget;

  //--------------------------------------------------------------------
  // GenXModule pass. Stores the information from various parts of the
  // GenX writing process
  class GenXModule : public ModulePass {
    const GenXSubtarget *ST = nullptr;
    LLVMContext *Ctx = nullptr;
    const GenXBackendConfig *BC = nullptr;

    // Visa option parser contains code that just stores c-strings as
    // pointers without copying. Store all strings here.
    BumpPtrAllocator ArgStorage;

    VISABuilder *CisaBuilder = nullptr;
    void InitCISABuilder();

    VISABuilder *VISAAsmTextReader = nullptr;
    void InitVISAAsmReader();

    bool InlineAsm = false;
    bool CheckForInlineAsm(Module &M) const;

    bool DisableFinalizerOpts = false;
    bool EmitDebugInformation = false;
    bool ImplicitArgsBufferIsUsed = false;
    // represents number of visa instructions in a *kernel*
    std::unordered_map<const Function *, unsigned> VisaCounter;
    // stores vISA mappings for each *function* (including kernel subroutines)
    std::unordered_map<const Function *, genx::di::VisaMapping> VisaMapping;

  private:
    void cleanup() {
      VisaMapping.clear();
      VisaCounter.clear();
      DestroyCISABuilder();
      DestroyVISAAsmReader();
      ArgStorage.Reset();
    }

  public:
    static char ID;

    // Additional info requred to create VISABuilder.
    struct InfoForFinalizer final {
      bool DisableFinalizerOpts = false;
      bool EmitDebugInformation = false;
      bool EmitCrossThreadOffsetRelocation = false;
    };

    explicit GenXModule() : ModulePass(ID) {}
    ~GenXModule() { cleanup(); }

    StringRef getPassName() const override { return "GenX module"; }
    void getAnalysisUsage(AnalysisUsage &AU) const override;
    bool runOnModule(Module &M) override;
    void releaseMemory() override { cleanup(); }

    const GenXSubtarget *getSubtarget() const { return ST; }
    bool HasInlineAsm() const { return InlineAsm; }
    VISABuilder *GetCisaBuilder();
    VISABuilder *GetVISAAsmReader();
    void DestroyCISABuilder();
    void DestroyVISAAsmReader();
    LLVMContext &getContext();

    bool emitDebugInformation() const { return EmitDebugInformation; }
    void updateVisaMapping(const Function *F, const Instruction *Inst,
                           unsigned VisaIndex, StringRef Reason);
    void updateVisaCountMapping(const Function *F, const Instruction *Inst,
                                unsigned VisaIndex, StringRef Reason);
    const genx::di::VisaMapping *getVisaMapping(const Function *F) const;
    // Returns additional info requred to create VISABuilder.
    // Subtarget must be already initialized before calling this method.
    InfoForFinalizer getInfoForFinalizer() const;
  };

  void initializeGenXModulePass(PassRegistry &);

} // end namespace llvm
#endif // ndef GENXMODULE_H