Home | History | Annotate | Download | only in src
      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.
     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 
     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::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;
    118   }
    119 }
    120 
    121 void Instrumentation::setHasSeenGlobals() {
    122   {
    123     std::unique_lock<std::mutex> _(GlobalsSeenMutex);
    124     HasSeenGlobals = true;
    125   }
    126   GlobalsSeenCV.notify_all();
    127 }
    128 
    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