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