blob: 0709bfce2d3ba370a00b7c4a0cbe7a5cbde1164c [file] [log] [blame]
Thomas Livelyaab70992016-06-07 13:54:59 -07001//===- 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
24namespace Ice {
25
26// Iterate through the instructions in the given CFG and instrument each one.
27// Also instrument the beginning of the function.
28void Instrumentation::instrumentFunc(Cfg *Func) {
29 assert(Func);
30 assert(!Func->getNodes().empty());
31
Thomas Lively3f97afb2016-07-07 14:56:21 -070032 if (!isInstrumentable(Func))
33 return;
34
35 bool DidInstrumentEntry = false;
Thomas Livelyaab70992016-06-07 13:54:59 -070036 LoweringContext Context;
37 Context.init(Func->getNodes().front());
Thomas Livelyaab70992016-06-07 13:54:59 -070038 for (CfgNode *Node : Func->getNodes()) {
39 Context.init(Node);
40 while (!Context.atEnd()) {
Thomas Lively3f97afb2016-07-07 14:56:21 -070041 if (!DidInstrumentEntry) {
Thomas Lively227c9f32016-06-21 11:43:07 -070042 instrumentFuncStart(Context);
Thomas Lively3f97afb2016-07-07 14:56:21 -070043 DidInstrumentEntry = true;
Thomas Lively227c9f32016-06-21 11:43:07 -070044 }
Thomas Livelyaab70992016-06-07 13:54:59 -070045 instrumentInst(Context);
46 // go to next undeleted instruction
47 Context.advanceCur();
48 Context.advanceNext();
49 }
50 }
Thomas Lively4e81fe02016-06-15 10:00:21 -070051
Thomas Lively26c43062016-06-17 15:53:24 -070052 std::string FuncName = Func->getFunctionName().toStringOrEmpty();
53 if (FuncName == "_start")
Thomas Lively4e81fe02016-06-15 10:00:21 -070054 instrumentStart(Func);
Thomas Lively1fd80c72016-06-27 14:47:21 -070055
56 finishFunc(Func);
Thomas Livelyaab70992016-06-07 13:54:59 -070057}
58
59void Instrumentation::instrumentInst(LoweringContext &Context) {
60 assert(!Context.atEnd());
61 Inst *Instr = iteratorToInst(Context.getCur());
62 switch (Instr->getKind()) {
Thomas Lively3f5cb6f2016-06-13 11:23:29 -070063 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::IntrinsicCall:
91 instrumentIntrinsicCall(Context, llvm::cast<InstIntrinsicCall>(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;
Thomas Livelyaab70992016-06-07 13:54:59 -0700118 }
119}
120
Thomas Lively2c9992a2016-07-20 11:19:17 -0700121void Instrumentation::setHasSeenGlobals() {
122 {
123 std::unique_lock<std::mutex> _(GlobalsSeenMutex);
124 HasSeenGlobals = true;
125 }
126 GlobalsSeenCV.notify_all();
127}
128
129LockedPtr<VariableDeclarationList> Instrumentation::getGlobals() {
130 std::unique_lock<std::mutex> GlobalsLock(GlobalsSeenMutex);
131 GlobalsSeenCV.wait(GlobalsLock, [this] { return HasSeenGlobals; });
132 return Ctx->getGlobals();
133}
134
Thomas Livelyaab70992016-06-07 13:54:59 -0700135} // end of namespace Ice