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