• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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