xref: /aosp_15_r20/external/swiftshader/third_party/subzero/src/IceInstrumentation.cpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1*03ce13f7SAndroid Build Coastguard Worker //===- subzero/src/IceInstrumentation.cpp - ICE instrumentation framework -===//
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker //                        The Subzero Code Generator
4*03ce13f7SAndroid Build Coastguard Worker //
5*03ce13f7SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*03ce13f7SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*03ce13f7SAndroid Build Coastguard Worker //
8*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*03ce13f7SAndroid Build Coastguard Worker ///
10*03ce13f7SAndroid Build Coastguard Worker /// \file
11*03ce13f7SAndroid Build Coastguard Worker /// \brief Implements the Ice::Instrumentation class.
12*03ce13f7SAndroid Build Coastguard Worker ///
13*03ce13f7SAndroid Build Coastguard Worker /// Subclasses can override particular instrumentation methods to specify how
14*03ce13f7SAndroid Build Coastguard Worker /// the the target program should be instrumented.
15*03ce13f7SAndroid Build Coastguard Worker ///
16*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
17*03ce13f7SAndroid Build Coastguard Worker 
18*03ce13f7SAndroid Build Coastguard Worker #include "IceInstrumentation.h"
19*03ce13f7SAndroid Build Coastguard Worker 
20*03ce13f7SAndroid Build Coastguard Worker #include "IceCfg.h"
21*03ce13f7SAndroid Build Coastguard Worker #include "IceInst.h"
22*03ce13f7SAndroid Build Coastguard Worker #include "IceTargetLowering.h"
23*03ce13f7SAndroid Build Coastguard Worker 
24*03ce13f7SAndroid Build Coastguard Worker namespace Ice {
25*03ce13f7SAndroid Build Coastguard Worker 
26*03ce13f7SAndroid Build Coastguard Worker // Iterate through the instructions in the given CFG and instrument each one.
27*03ce13f7SAndroid Build Coastguard Worker // Also instrument the beginning of the function.
instrumentFunc(Cfg * Func)28*03ce13f7SAndroid Build Coastguard Worker void Instrumentation::instrumentFunc(Cfg *Func) {
29*03ce13f7SAndroid Build Coastguard Worker   assert(Func);
30*03ce13f7SAndroid Build Coastguard Worker   assert(!Func->getNodes().empty());
31*03ce13f7SAndroid Build Coastguard Worker 
32*03ce13f7SAndroid Build Coastguard Worker   if (!isInstrumentable(Func))
33*03ce13f7SAndroid Build Coastguard Worker     return;
34*03ce13f7SAndroid Build Coastguard Worker 
35*03ce13f7SAndroid Build Coastguard Worker   bool DidInstrumentEntry = false;
36*03ce13f7SAndroid Build Coastguard Worker   LoweringContext Context;
37*03ce13f7SAndroid Build Coastguard Worker   Context.init(Func->getNodes().front());
38*03ce13f7SAndroid Build Coastguard Worker   for (CfgNode *Node : Func->getNodes()) {
39*03ce13f7SAndroid Build Coastguard Worker     Context.init(Node);
40*03ce13f7SAndroid Build Coastguard Worker     while (!Context.atEnd()) {
41*03ce13f7SAndroid Build Coastguard Worker       if (!DidInstrumentEntry) {
42*03ce13f7SAndroid Build Coastguard Worker         instrumentFuncStart(Context);
43*03ce13f7SAndroid Build Coastguard Worker         DidInstrumentEntry = true;
44*03ce13f7SAndroid Build Coastguard Worker       }
45*03ce13f7SAndroid Build Coastguard Worker       instrumentInst(Context);
46*03ce13f7SAndroid Build Coastguard Worker       // go to next undeleted instruction
47*03ce13f7SAndroid Build Coastguard Worker       Context.advanceCur();
48*03ce13f7SAndroid Build Coastguard Worker       Context.advanceNext();
49*03ce13f7SAndroid Build Coastguard Worker     }
50*03ce13f7SAndroid Build Coastguard Worker   }
51*03ce13f7SAndroid Build Coastguard Worker 
52*03ce13f7SAndroid Build Coastguard Worker   std::string FuncName = Func->getFunctionName().toStringOrEmpty();
53*03ce13f7SAndroid Build Coastguard Worker   if (FuncName == "_start")
54*03ce13f7SAndroid Build Coastguard Worker     instrumentStart(Func);
55*03ce13f7SAndroid Build Coastguard Worker 
56*03ce13f7SAndroid Build Coastguard Worker   finishFunc(Func);
57*03ce13f7SAndroid Build Coastguard Worker }
58*03ce13f7SAndroid Build Coastguard Worker 
instrumentInst(LoweringContext & Context)59*03ce13f7SAndroid Build Coastguard Worker void Instrumentation::instrumentInst(LoweringContext &Context) {
60*03ce13f7SAndroid Build Coastguard Worker   assert(!Context.atEnd());
61*03ce13f7SAndroid Build Coastguard Worker   Inst *Instr = iteratorToInst(Context.getCur());
62*03ce13f7SAndroid Build Coastguard Worker   switch (Instr->getKind()) {
63*03ce13f7SAndroid Build Coastguard Worker   case Inst::Alloca:
64*03ce13f7SAndroid Build Coastguard Worker     instrumentAlloca(Context, llvm::cast<InstAlloca>(Instr));
65*03ce13f7SAndroid Build Coastguard Worker     break;
66*03ce13f7SAndroid Build Coastguard Worker   case Inst::Arithmetic:
67*03ce13f7SAndroid Build Coastguard Worker     instrumentArithmetic(Context, llvm::cast<InstArithmetic>(Instr));
68*03ce13f7SAndroid Build Coastguard Worker     break;
69*03ce13f7SAndroid Build Coastguard Worker   case Inst::Br:
70*03ce13f7SAndroid Build Coastguard Worker     instrumentBr(Context, llvm::cast<InstBr>(Instr));
71*03ce13f7SAndroid Build Coastguard Worker     break;
72*03ce13f7SAndroid Build Coastguard Worker   case Inst::Call:
73*03ce13f7SAndroid Build Coastguard Worker     instrumentCall(Context, llvm::cast<InstCall>(Instr));
74*03ce13f7SAndroid Build Coastguard Worker     break;
75*03ce13f7SAndroid Build Coastguard Worker   case Inst::Cast:
76*03ce13f7SAndroid Build Coastguard Worker     instrumentCast(Context, llvm::cast<InstCast>(Instr));
77*03ce13f7SAndroid Build Coastguard Worker     break;
78*03ce13f7SAndroid Build Coastguard Worker   case Inst::ExtractElement:
79*03ce13f7SAndroid Build Coastguard Worker     instrumentExtractElement(Context, llvm::cast<InstExtractElement>(Instr));
80*03ce13f7SAndroid Build Coastguard Worker     break;
81*03ce13f7SAndroid Build Coastguard Worker   case Inst::Fcmp:
82*03ce13f7SAndroid Build Coastguard Worker     instrumentFcmp(Context, llvm::cast<InstFcmp>(Instr));
83*03ce13f7SAndroid Build Coastguard Worker     break;
84*03ce13f7SAndroid Build Coastguard Worker   case Inst::Icmp:
85*03ce13f7SAndroid Build Coastguard Worker     instrumentIcmp(Context, llvm::cast<InstIcmp>(Instr));
86*03ce13f7SAndroid Build Coastguard Worker     break;
87*03ce13f7SAndroid Build Coastguard Worker   case Inst::InsertElement:
88*03ce13f7SAndroid Build Coastguard Worker     instrumentInsertElement(Context, llvm::cast<InstInsertElement>(Instr));
89*03ce13f7SAndroid Build Coastguard Worker     break;
90*03ce13f7SAndroid Build Coastguard Worker   case Inst::Intrinsic:
91*03ce13f7SAndroid Build Coastguard Worker     instrumentIntrinsic(Context, llvm::cast<InstIntrinsic>(Instr));
92*03ce13f7SAndroid Build Coastguard Worker     break;
93*03ce13f7SAndroid Build Coastguard Worker   case Inst::Load:
94*03ce13f7SAndroid Build Coastguard Worker     instrumentLoad(Context, llvm::cast<InstLoad>(Instr));
95*03ce13f7SAndroid Build Coastguard Worker     break;
96*03ce13f7SAndroid Build Coastguard Worker   case Inst::Phi:
97*03ce13f7SAndroid Build Coastguard Worker     instrumentPhi(Context, llvm::cast<InstPhi>(Instr));
98*03ce13f7SAndroid Build Coastguard Worker     break;
99*03ce13f7SAndroid Build Coastguard Worker   case Inst::Ret:
100*03ce13f7SAndroid Build Coastguard Worker     instrumentRet(Context, llvm::cast<InstRet>(Instr));
101*03ce13f7SAndroid Build Coastguard Worker     break;
102*03ce13f7SAndroid Build Coastguard Worker   case Inst::Select:
103*03ce13f7SAndroid Build Coastguard Worker     instrumentSelect(Context, llvm::cast<InstSelect>(Instr));
104*03ce13f7SAndroid Build Coastguard Worker     break;
105*03ce13f7SAndroid Build Coastguard Worker   case Inst::Store:
106*03ce13f7SAndroid Build Coastguard Worker     instrumentStore(Context, llvm::cast<InstStore>(Instr));
107*03ce13f7SAndroid Build Coastguard Worker     break;
108*03ce13f7SAndroid Build Coastguard Worker   case Inst::Switch:
109*03ce13f7SAndroid Build Coastguard Worker     instrumentSwitch(Context, llvm::cast<InstSwitch>(Instr));
110*03ce13f7SAndroid Build Coastguard Worker     break;
111*03ce13f7SAndroid Build Coastguard Worker   case Inst::Unreachable:
112*03ce13f7SAndroid Build Coastguard Worker     instrumentUnreachable(Context, llvm::cast<InstUnreachable>(Instr));
113*03ce13f7SAndroid Build Coastguard Worker     break;
114*03ce13f7SAndroid Build Coastguard Worker   default:
115*03ce13f7SAndroid Build Coastguard Worker     // Only instrument high-level ICE instructions
116*03ce13f7SAndroid Build Coastguard Worker     assert(false && "Instrumentation encountered an unexpected instruction");
117*03ce13f7SAndroid Build Coastguard Worker     break;
118*03ce13f7SAndroid Build Coastguard Worker   }
119*03ce13f7SAndroid Build Coastguard Worker }
120*03ce13f7SAndroid Build Coastguard Worker 
setHasSeenGlobals()121*03ce13f7SAndroid Build Coastguard Worker void Instrumentation::setHasSeenGlobals() {
122*03ce13f7SAndroid Build Coastguard Worker   {
123*03ce13f7SAndroid Build Coastguard Worker     std::unique_lock<std::mutex> _(GlobalsSeenMutex);
124*03ce13f7SAndroid Build Coastguard Worker     HasSeenGlobals = true;
125*03ce13f7SAndroid Build Coastguard Worker   }
126*03ce13f7SAndroid Build Coastguard Worker   GlobalsSeenCV.notify_all();
127*03ce13f7SAndroid Build Coastguard Worker }
128*03ce13f7SAndroid Build Coastguard Worker 
getGlobals()129*03ce13f7SAndroid Build Coastguard Worker LockedPtr<VariableDeclarationList> Instrumentation::getGlobals() {
130*03ce13f7SAndroid Build Coastguard Worker   std::unique_lock<std::mutex> GlobalsLock(GlobalsSeenMutex);
131*03ce13f7SAndroid Build Coastguard Worker   GlobalsSeenCV.wait(GlobalsLock, [this] { return HasSeenGlobals; });
132*03ce13f7SAndroid Build Coastguard Worker   return Ctx->getGlobals();
133*03ce13f7SAndroid Build Coastguard Worker }
134*03ce13f7SAndroid Build Coastguard Worker 
135*03ce13f7SAndroid Build Coastguard Worker } // end of namespace Ice
136