Beispiel #1
0
/// findFunctionScopedAllocas - store all allocas that are known to be valid
/// to the end of their function in a set. The current algorithm does this by
/// finding all the allocas in the entry block that are before the first
/// llvm.stacksave call (if any).
///
/// FIXME: There can also be allocas elsewhere that get deallocated at the end
/// of the function but they are pessimistically ignored for now.
///
void ExactCheckOpt::findFunctionScopedAllocas(Module &M) {
  for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
    if (F->empty())
      continue;

    BasicBlock &BB = F->getEntryBlock();
    for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I) {
      if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) {
        FunctionScopedAllocas.insert(AI);
      } else if(CallInst *CI = dyn_cast<CallInst>(I)) {
        Function *CalledFunction = CI->getCalledFunction();
        if (CalledFunction && CalledFunction->getName() == "llvm.stacksave")
          break;
      }
    }
  }
}
bool TraceBasicBlocks::runOnModule(Module &M)  {
	Context =&M.getContext();
	Function *Main = M.getFunction("main");
	if (Main == 0) {
		errs() << "WARNING: cannot insert basic-block trace instrumentation"
			<< " into a module with no main function!\n";
		return false;  // No main, no instrumentation!
	}
	const char* FnName="llvm_trace_basic_block";
	Constant *InstrFn = M.getOrInsertFunction (FnName, Type::getVoidTy(*Context),
	                                           Type::getInt64Ty(*Context), NULL);

	unsigned BBNumber = 0;
	for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
		if(F->empty()) { continue; }
		//We insert instrumentation calls in reverse order, because insertion puts them before previous instructions
		for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
			dbgs() << "InsertInstrumentationCall (\"" << BB->getName ()
				<< "\", \"" << F->getName() << "\", " << BBNumber << ")\n";

			//On Exit we emit the FunRet block
			TerminatorInst* TI=BB->getTerminator();
			if(TI->getNumSuccessors()==0) {
				InsertRetInstrumentationCall(TI,InstrFn);
			}
			InsertInstrumentationCall (BB, InstrFn, BBNumber);
			if(TraceMemory) {
				InsertMemoryTracingCall (BB,InstrFn);
			}
			++BBNumber;
		}
		//on Entry we emit the FunCall block.
		BasicBlock* EntryBlock=&F->getEntryBlock();
		InsertInstrumentationCall (EntryBlock, InstrFn, BBTraceStream::FunCallID);
	}

	// Add the initialization call to main.

	InsertProfilingInitCall(Main, "llvm_start_basic_block_tracing");
	return true;
}
/// matchEdges - Link every profile counter with an edge.
unsigned ProfileMetadataLoaderPass::matchEdges(Module &M, ProfileData &PB,
                                               ArrayRef<unsigned> Counters) {
  if (Counters.size() == 0) return 0;

  unsigned ReadCount = 0;

  for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
    if (F->isDeclaration()) continue;
    DEBUG(dbgs() << "Loading edges in '" << F->getName() << "'\n");
    readEdge(ReadCount++, PB, PB.getEdge(0, &F->getEntryBlock()), Counters);
    for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
      TerminatorInst *TI = BB->getTerminator();
      for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) {
        readEdge(ReadCount++, PB, PB.getEdge(BB,TI->getSuccessor(s)),
                 Counters);
      }
    }
  }

  return ReadCount;
}
bool MLStatic::runOnModule(Module &M) {

	for(Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
		if (F->isDeclaration()) continue;
      	   	errs()<<"---Running for Function:"<<F->getName()<<"\n";
	   	DT = &getAnalysis<DominatorTree>(*F);
		BasicBlock *BB = &(F->getEntryBlock());     
		tracePath(BB);
   	 }

	 DEBUG(dbgs()<<"PATH collection Complete\n");
	for(Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
	 for(int i=0;i<pathCollecn2[F].size();++i){
		for(int j=0;j<pathCollecn2[F][i].size();++j){
			DEBUG(dbgs()<<pathCollecn2[F][i][j]->getName()<<" ");
		}
		DEBUG(dbgs()<<"\n");
       	}
	}

	expandPathAll(M);
	 return false;
}
bool PrintFunctionNames::runOnModule(Module &M) {

  errs() << "Pass PrintFunctionNames\n";

  // iterating through functions
  for(Module::iterator f = M.begin(), fe = M.end(); f != fe; f++) {

    if (!f->isDeclaration()) {
      // finding and printing file information 
      BasicBlock &block = f->getEntryBlock();
      Instruction &inst = block.front();
      
      if (MDNode *node = inst.getMetadata("dbg")) {
	DILocation loc(node);
	errs() << "File name: " << loc.getFilename() << "\t";
      }
    }
      
    // finding and printing function informatonion
    errs() << "Function name: " << f->getName() << "\n";
  }

  return false;
}  
bool OptimalEdgeProfiler::runOnModule(Module &M) {
  Function *Main = M.getFunction("main");
  if (Main == 0) {
    errs() << "WARNING: cannot insert edge profiling into a module"
           << " with no main function!\n";
    return false;  // No main, no instrumentation!
  }

  // NumEdges counts all the edges that may be instrumented. Later on its
  // decided which edges to actually instrument, to achieve optimal profiling.
  // For the entry block a virtual edge (0,entry) is reserved, for each block
  // with no successors an edge (BB,0) is reserved. These edges are necessary
  // to calculate a truly optimal maximum spanning tree and thus an optimal
  // instrumentation.
  unsigned NumEdges = 0;

  for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
    if (F->isDeclaration()) continue;
    // Reserve space for (0,entry) edge.
    ++NumEdges;
    for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
      // Keep track of which blocks need to be instrumented.  We don't want to
      // instrument blocks that are added as the result of breaking critical
      // edges!
      if (BB->getTerminator()->getNumSuccessors() == 0) {
        // Reserve space for (BB,0) edge.
        ++NumEdges;
      } else {
        NumEdges += BB->getTerminator()->getNumSuccessors();
      }
    }
  }

  // In the profiling output a counter for each edge is reserved, but only few
  // are used. This is done to be able to read back in the profile without
  // calulating the maximum spanning tree again, instead each edge counter that
  // is not used is initialised with -1 to signal that this edge counter has to
  // be calculated from other edge counters on reading the profile info back
  // in.

  const Type *Int32 = Type::getInt32Ty(M.getContext());
  const ArrayType *ATy = ArrayType::get(Int32, NumEdges);
  GlobalVariable *Counters =
    new GlobalVariable(M, ATy, false, GlobalValue::InternalLinkage,
                       Constant::getNullValue(ATy), "OptEdgeProfCounters");
  NumEdgesInserted = 0;

  std::vector<Constant*> Initializer(NumEdges);
  Constant* Zero = ConstantInt::get(Int32, 0);
  Constant* Uncounted = ConstantInt::get(Int32, ProfileInfoLoader::Uncounted);

  // Instrument all of the edges not in MST...
  unsigned i = 0;
  for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
    if (F->isDeclaration()) continue;
    DEBUG(dbgs()<<"Working on "<<F->getNameStr()<<"\n");

    // Calculate a Maximum Spanning Tree with the edge weights determined by
    // ProfileEstimator. ProfileEstimator also assign weights to the virtual
    // edges (0,entry) and (BB,0) (for blocks with no successors) and this
    // edges also participate in the maximum spanning tree calculation.
    // The third parameter of MaximumSpanningTree() has the effect that not the
    // actual MST is returned but the edges _not_ in the MST.

    ProfileInfo::EdgeWeights ECs =
      getAnalysis<ProfileInfo>(*F).getEdgeWeights(F);
    std::vector<ProfileInfo::EdgeWeight> EdgeVector(ECs.begin(), ECs.end());
    MaximumSpanningTree<BasicBlock> MST (EdgeVector);
    std::stable_sort(MST.begin(),MST.end());

    // Check if (0,entry) not in the MST. If not, instrument edge
    // (IncrementCounterInBlock()) and set the counter initially to zero, if
    // the edge is in the MST the counter is initialised to -1.

    BasicBlock *entry = &(F->getEntryBlock());
    ProfileInfo::Edge edge = ProfileInfo::getEdge(0,entry);
    if (!std::binary_search(MST.begin(), MST.end(), edge)) {
      printEdgeCounter(edge,entry,i);
      IncrementCounterInBlock(entry, i, Counters); ++NumEdgesInserted;
      Initializer[i++] = (Zero);
    } else{
      Initializer[i++] = (Uncounted);
    }

    // InsertedBlocks contains all blocks that were inserted for splitting an
    // edge, this blocks do not have to be instrumented.
    DenseSet<BasicBlock*> InsertedBlocks;
    for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
      // Check if block was not inserted and thus does not have to be
      // instrumented.
      if (InsertedBlocks.count(BB)) continue;

      // Okay, we have to add a counter of each outgoing edge not in MST. If
      // the outgoing edge is not critical don't split it, just insert the
      // counter in the source or destination of the edge. Also, if the block
      // has no successors, the virtual edge (BB,0) is processed.
      TerminatorInst *TI = BB->getTerminator();
      if (TI->getNumSuccessors() == 0) {
        ProfileInfo::Edge edge = ProfileInfo::getEdge(BB,0);
        if (!std::binary_search(MST.begin(), MST.end(), edge)) {
          printEdgeCounter(edge,BB,i);
          IncrementCounterInBlock(BB, i, Counters); ++NumEdgesInserted;
          Initializer[i++] = (Zero);
        } else{
          Initializer[i++] = (Uncounted);
        }
      }
      for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) {
        BasicBlock *Succ = TI->getSuccessor(s);
        ProfileInfo::Edge edge = ProfileInfo::getEdge(BB,Succ);
        if (!std::binary_search(MST.begin(), MST.end(), edge)) {

          // If the edge is critical, split it.
          bool wasInserted = SplitCriticalEdge(TI, s, this);
          Succ = TI->getSuccessor(s);
          if (wasInserted)
            InsertedBlocks.insert(Succ);

          // Okay, we are guaranteed that the edge is no longer critical.  If
          // we only have a single successor, insert the counter in this block,
          // otherwise insert it in the successor block.
          if (TI->getNumSuccessors() == 1) {
            // Insert counter at the start of the block
            printEdgeCounter(edge,BB,i);
            IncrementCounterInBlock(BB, i, Counters); ++NumEdgesInserted;
          } else {
            // Insert counter at the start of the block
            printEdgeCounter(edge,Succ,i);
            IncrementCounterInBlock(Succ, i, Counters); ++NumEdgesInserted;
          }
          Initializer[i++] = (Zero);
        } else {
          Initializer[i++] = (Uncounted);
        }
      }
    }
  }

  // Check if the number of edges counted at first was the number of edges we
  // considered for instrumentation.
  assert(i==NumEdges && "the number of edges in counting array is wrong");

  // Assing the now completely defined initialiser to the array.
  Constant *init = ConstantArray::get(ATy, Initializer);
  Counters->setInitializer(init);

  // Add the initialization call to main.
  InsertProfilingInitCall(Main, "llvm_start_opt_edge_profiling", Counters);
  return true;
}
Beispiel #7
0
bool EdgeProfiler::runOnModule(Module &M) {
  Function *Main = M.getFunction("main");
  if (Main == 0) {
    errs() << "WARNING: cannot insert edge profiling into a module"
           << " with no main function!\n";
    return false;  // No main, no instrumentation!
  }

  std::set<BasicBlock*> BlocksToInstrument;
  unsigned NumEdges = 0;
  for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
    if (F->isDeclaration()) continue;
    // Reserve space for (0,entry) edge.
    ++NumEdges;
    for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
      // Keep track of which blocks need to be instrumented.  We don't want to
      // instrument blocks that are added as the result of breaking critical
      // edges!
      BlocksToInstrument.insert(BB);
      NumEdges += BB->getTerminator()->getNumSuccessors();
    }
  }

  Type *ATy = ArrayType::get(Type::getInt32Ty(M.getContext()), NumEdges);
  GlobalVariable *Counters =
    new GlobalVariable(M, ATy, false, GlobalValue::InternalLinkage,
                       Constant::getNullValue(ATy), "EdgeProfCounters");
  NumEdgesInserted = NumEdges;

  // Instrument all of the edges...
  unsigned i = 0;
  for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
    if (F->isDeclaration()) continue;
    // Create counter for (0,entry) edge.
    IncrementCounterInBlock(&F->getEntryBlock(), i++, Counters);
    for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
      if (BlocksToInstrument.count(BB)) {  // Don't instrument inserted blocks
        // Okay, we have to add a counter of each outgoing edge.  If the
        // outgoing edge is not critical don't split it, just insert the counter
        // in the source or destination of the edge.
        TerminatorInst *TI = BB->getTerminator();
        for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) {
          // If the edge is critical, split it.
          SplitCriticalEdge(TI, s, this);

          // Okay, we are guaranteed that the edge is no longer critical.  If we
          // only have a single successor, insert the counter in this block,
          // otherwise insert it in the successor block.
          if (TI->getNumSuccessors() == 1) {
            // Insert counter at the start of the block
            IncrementCounterInBlock(BB, i++, Counters, false);
          } else {
            // Insert counter at the start of the block
            IncrementCounterInBlock(TI->getSuccessor(s), i++, Counters);
          }
        }
      }
  }

  // Add the initialization call to main.
  InsertProfilingInitCall(Main, "llvm_start_edge_profiling", Counters);
  return true;
}
bool LoaderPass::runOnModule(Module &M) {
  ProfileInfoLoader PIL("profile-loader", Filename);

  EdgeInformation.clear();
  std::vector<uint64_t> Counters64 = PIL.getRawEdgeCounts();
  if (Counters64.size() > 0) {
    ReadCount = 0;
    std::vector<uint64_t>& Counters = Counters64;
    for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
      if (F->isDeclaration()) continue;
      DEBUG(dbgs() << "Working on " << F->getName() << "\n");
      readEdge(getEdge(0,&F->getEntryBlock()), Counters);
      for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
        TerminatorInst *TI = BB->getTerminator();
        for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) {
          readEdge(getEdge(BB,TI->getSuccessor(s)), Counters);
        }
      }
    }
    if (ReadCount != Counters.size()) {
      errs() << "WARNING: profile information is inconsistent with "
             << "the current program!\n";
    }
    NumEdgesRead = ReadCount;
  }

#if 0
  std::vector<unsigned> Counters = PIL.getRawOptimalEdgeCounts();
  if (Counters.size() > 0) {
    ReadCount = 0;
    for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
      if (F->isDeclaration()) continue;
      DEBUG(dbgs() << "Working on " << F->getName() << "\n");
      readEdge(getEdge(0,&F->getEntryBlock()), Counters);
      for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
        TerminatorInst *TI = BB->getTerminator();
        if (TI->getNumSuccessors() == 0) {
          readEdge(getEdge(BB,0), Counters);
        }
        for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) {
          readEdge(getEdge(BB,TI->getSuccessor(s)), Counters);
        }
      }
      while (SpanningTree.size() > 0) {

        unsigned size = SpanningTree.size();

        BBisUnvisited.clear();
        for (std::set<Edge>::iterator ei = SpanningTree.begin(),
             ee = SpanningTree.end(); ei != ee; ++ei) {
          BBisUnvisited.insert(ei->first);
          BBisUnvisited.insert(ei->second);
        }
        while (BBisUnvisited.size() > 0) {
          recurseBasicBlock(*BBisUnvisited.begin());
        }

        if (SpanningTree.size() == size) {
          DEBUG(dbgs()<<"{");
          for (std::set<Edge>::iterator ei = SpanningTree.begin(),
               ee = SpanningTree.end(); ei != ee; ++ei) {
            DEBUG(dbgs()<< *ei <<",");
          }
          assert(0 && "No edge calculated!");
        }

      }
    }
    if (ReadCount != Counters.size()) {
      errs() << "WARNING: profile information is inconsistent with "
             << "the current program!\n";
    }
    NumEdgesRead = ReadCount;
  }
#endif

  BlockInformation.clear();
  Counters64 = PIL.getRawBlockCounts();
  if (Counters64.size() > 0) {
    std::vector<uint64_t>& Counters = Counters64;
    ReadCount = 0;
    for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
      if (F->isDeclaration()) continue;
      for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
        if (ReadCount < Counters.size())
          // Here the data realm changes from the unsigned of the file to the
          // double of the ProfileInfo. This conversion is save because we know
          // that everything thats representable in unsinged is also
          // representable in double.
          BlockInformation[F][BB] = (double)Counters[ReadCount++];
    }
    if (ReadCount != Counters.size()) {
      errs() << "WARNING: profile information is inconsistent with "
             << "the current program!\n";
    }
  }

  FunctionInformation.clear();
  std::vector<unsigned> Counters = PIL.getRawFunctionCounts();
  if (Counters.size() > 0) {
    ReadCount = 0;
    for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
      if (F->isDeclaration()) continue;
      if (ReadCount < Counters.size())
        // Here the data realm changes from the unsigned of the file to the
        // double of the ProfileInfo. This conversion is save because we know
        // that everything thats representable in unsinged is also
        // representable in double.
        FunctionInformation[F] = (double)Counters[ReadCount++];
    }
    if (ReadCount != Counters.size()) {
      errs() << "WARNING: profile information is inconsistent with "
             << "the current program!\n";
    }
  }

  ValueInformation.clear();
  Counters = PIL.getRawValueCounts();
  if(Counters.size() > 0) {
	  ReadCount = 0;
	  for(Module::iterator F = M.begin(),E = M.end(); F!= E; ++F) {
		  if (F->isDeclaration()) continue;
		  for(inst_iterator I = inst_begin(F),IE = inst_end(F); I!=IE; ++I){
			  CallInst* Call = dyn_cast<CallInst>(&*I);
           if(!Call) continue;
			  if(Call->getCalledValue()->getName() != "llvm_profiling_trap_value") continue;
			  unsigned index = getTrapedIndex(Call);
			  ValueCounts Ins;
			  Ins.Nums = Counters[index];
			  const std::vector<int>& content = PIL.getRawValueContent(index);
			  Ins.flags = (ProfilingFlags)content.front();
			  Ins.Contents.resize(content.size()-1);
			  copy(content.begin()+1,content.end(),Ins.Contents.begin());
			  //should NOT insert two values into one cell.
			  ValueInformation[Call] = Ins;
		  }
	  }
  }

  SLGInformation.clear();
  Counters = PIL.getRawSLGCounts();
  if(Counters.size() > 0) {
     unsigned MaxStore = std::accumulate(Counters.begin(), Counters.end(), 0, sig_max);
     std::vector<const Instruction*> Cache(MaxStore+1);
     ReadCount = 0; 
     unsigned load_idx = 0, store_idx = 1;
     for(Module::iterator F = M.begin(), E = M.end(); F!=E; ++F){
        for(inst_iterator I = inst_begin(F), IE = inst_end(F); I!=IE; ++I){
           if(!isa<StoreInst>(&*I) && !isa<LoadInst>(&*I)) continue;
           if(lle::access_global_variable(&*I)){
              unsigned index = 0;
              Instruction* SLI = &*I;
              if(isa<StoreInst>(&*I)){
                 index = store_idx++;
              }else if(LoadInst* LI = dyn_cast<LoadInst>(&*I)){
                 SLGInformation[LI] = std::make_pair(load_idx, (Instruction*)NULL);
                 index = Counters[load_idx++];
                 if(index == 0 || index == ~0U/*unsigned -1*/){ 
                    continue;
                 }
              }
              if(index >= Cache.size()) continue;
              if(Cache[index]){
                 const Instruction* SLJ = Cache[index];
                 if(isa<StoreInst>(SLJ) && isa<LoadInst>(SLI)) SLGInformation[SLI].second = SLJ;
                 else if(isa<StoreInst>(SLI) && isa<LoadInst>(SLJ)) SLGInformation[SLJ].second = SLI;
                 else
                    assert(0 && "It shouldn't happen");
              }else
                 Cache[index] = &*I;
           }
        }
     }
  }

  MPInformation.clear();
  Counters = PIL.getRawMPICounts();
  if(Counters.size() > 0) {
     ReadCount = 0;
     for(auto F = M.begin(), E = M.end(); F!=E; ++F){
        for(auto I = inst_begin(F), IE = inst_end(F); I!=IE; ++I){
           CallInst* CI = dyn_cast<CallInst>(&*I);
           if(CI == NULL) continue;
           if(lle::get_mpi_count_idx(CI)){
              MPInformation[CI] = std::make_pair(ReadCount, Counters[ReadCount]);
              ++ReadCount;
           }
        }
     }
  }

  MPIFullInformation.clear();
  Counters = PIL.getRawMPIFullCounts();
  if(Counters.size() > 0) {
     ReadCount = 0;
     for(auto F = M.begin(), E = M.end(); F!=E; ++F){
        for(auto I = inst_begin(F), IE = inst_end(F); I!=IE; ++I){
           CallInst* CI = dyn_cast<CallInst>(&*I);
           if(CI == NULL) continue;
           if(lle::get_mpi_count_idx(CI)){
              MPIFullInformation[CI] = std::make_pair(ReadCount, Counters[ReadCount]);
              ++ReadCount;
           }
        }
     }
  }

  return false;
}
Beispiel #9
0
// the verifier iterates through each path to gather the total
// number of edge frequencies
bool PathProfileVerifier::runOnModule (Module &M) {
  PathProfileInfo& pathProfileInfo = getAnalysis<PathProfileInfo>();

  // setup a data structure to map path edges which index an
  // array of edge counters
  NestedBlockToIndexMap arrayMap;
  unsigned i = 0;
  for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
    if (F->isDeclaration()) continue;

    arrayMap[0][F->begin()][0] = i++;

    for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
      TerminatorInst *TI = BB->getTerminator();

      unsigned duplicate = 0;
      BasicBlock* prev = 0;
      for (unsigned s = 0, e = TI->getNumSuccessors(); s != e;
           prev = TI->getSuccessor(s), ++s) {
        if (prev == TI->getSuccessor(s))
          duplicate++;
        else duplicate = 0;

        arrayMap[BB][TI->getSuccessor(s)][duplicate] = i++;
      }
    }
  }

  std::vector<unsigned> edgeArray(i);

  // iterate through each path and increment the edge counters as needed
  for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
    if (F->isDeclaration()) continue;

    pathProfileInfo.setCurrentFunction(F);

    DEBUG(dbgs() << "function '" << F->getName() << "' ran "
          << pathProfileInfo.pathsRun()
          << "/" << pathProfileInfo.getPotentialPathCount()
          << " potential paths\n");

    for( ProfilePathIterator nextPath = pathProfileInfo.pathBegin(),
           endPath = pathProfileInfo.pathEnd();
         nextPath != endPath; nextPath++ ) {
      ProfilePath* currentPath = nextPath->second;

      ProfilePathEdgeVector* pev = currentPath->getPathEdges();
      DEBUG(dbgs () << "path #" << currentPath->getNumber() << ": "
            << currentPath->getCount() << "\n");
      // setup the entry edge (normally path profiling doesn't care about this)
      if (currentPath->getFirstBlockInPath() == &F->getEntryBlock())
        edgeArray[arrayMap[0][currentPath->getFirstBlockInPath()][0]]
          += currentPath->getCount();

      for( ProfilePathEdgeIterator nextEdge = pev->begin(),
             endEdge = pev->end(); nextEdge != endEdge; nextEdge++ ) {
        if (nextEdge != pev->begin())
          DEBUG(dbgs() << " :: ");

        BasicBlock* source = nextEdge->getSource();
        BasicBlock* target = nextEdge->getTarget();
        unsigned duplicateNumber = nextEdge->getDuplicateNumber();
        DEBUG(dbgs() << source->getName() << " --{" << duplicateNumber
                     << "}--> " << target->getName());

        // Ensure all the referenced edges exist
        // TODO: make this a separate function
        if( !arrayMap.count(source) ) {
          errs() << "  error [" << F->getName() << "()]: source '"
                 << source->getName()
                 << "' does not exist in the array map.\n";
        } else if( !arrayMap[source].count(target) ) {
          errs() << "  error [" << F->getName() << "()]: target '"
                 << target->getName()
                 << "' does not exist in the array map.\n";
        } else if( !arrayMap[source][target].count(duplicateNumber) ) {
          errs() << "  error [" << F->getName() << "()]: edge "
                 << source->getName() << " -> " << target->getName()
                 << " duplicate number " << duplicateNumber
                 << " does not exist in the array map.\n";
        } else {
          edgeArray[arrayMap[source][target][duplicateNumber]]
            += currentPath->getCount();
        }
      }

      DEBUG(errs() << "\n");

      delete pev;
    }
  }

  std::string errorInfo;
  std::string filename = EdgeProfileFilename;

  // Open a handle to the file
  FILE* edgeFile = fopen(filename.c_str(),"wb");

  if (!edgeFile) {
    errs() << "error: unable to open file '" << filename << "' for output.\n";
    return false;
  }

  errs() << "Generating edge profile '" << filename << "' ...\n";

  // write argument info
  unsigned type = ArgumentInfo;
  unsigned num = pathProfileInfo.argList.size();
  int zeros = 0;

  fwrite(&type,sizeof(unsigned),1,edgeFile);
  fwrite(&num,sizeof(unsigned),1,edgeFile);
  fwrite(pathProfileInfo.argList.c_str(),1,num,edgeFile);
  if (num&3)
    fwrite(&zeros, 1, 4-(num&3), edgeFile);

  type = EdgeInfo;
  num = edgeArray.size();
  fwrite(&type,sizeof(unsigned),1,edgeFile);
  fwrite(&num,sizeof(unsigned),1,edgeFile);

  // write each edge to the file
  for( std::vector<unsigned>::iterator s = edgeArray.begin(),
         e = edgeArray.end(); s != e; s++)
    fwrite(&*s, sizeof (unsigned), 1, edgeFile);

  fclose (edgeFile);

  return true;
}
Beispiel #10
0
bool GenericToNVVM::runOnModule(Module &M) {
  // Create a clone of each global variable that has the default address space.
  // The clone is created with the global address space  specifier, and the pair
  // of original global variable and its clone is placed in the GVMap for later
  // use.

  for (Module::global_iterator I = M.global_begin(), E = M.global_end();
       I != E;) {
    GlobalVariable *GV = &*I++;
    if (GV->getType()->getAddressSpace() == llvm::ADDRESS_SPACE_GENERIC &&
        !llvm::isTexture(*GV) && !llvm::isSurface(*GV) &&
        !llvm::isSampler(*GV) && !GV->getName().startswith("llvm.")) {
      GlobalVariable *NewGV = new GlobalVariable(
          M, GV->getValueType(), GV->isConstant(),
          GV->getLinkage(),
          GV->hasInitializer() ? GV->getInitializer() : nullptr,
          "", GV, GV->getThreadLocalMode(), llvm::ADDRESS_SPACE_GLOBAL);
      NewGV->copyAttributesFrom(GV);
      GVMap[GV] = NewGV;
    }
  }

  // Return immediately, if every global variable has a specific address space
  // specifier.
  if (GVMap.empty()) {
    return false;
  }

  // Walk through the instructions in function defitinions, and replace any use
  // of original global variables in GVMap with a use of the corresponding
  // copies in GVMap.  If necessary, promote constants to instructions.
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
    if (I->isDeclaration()) {
      continue;
    }
    IRBuilder<> Builder(I->getEntryBlock().getFirstNonPHIOrDbg());
    for (Function::iterator BBI = I->begin(), BBE = I->end(); BBI != BBE;
         ++BBI) {
      for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE;
           ++II) {
        for (unsigned i = 0, e = II->getNumOperands(); i < e; ++i) {
          Value *Operand = II->getOperand(i);
          if (isa<Constant>(Operand)) {
            II->setOperand(
                i, remapConstant(&M, &*I, cast<Constant>(Operand), Builder));
          }
        }
      }
    }
    ConstantToValueMap.clear();
  }

  // Copy GVMap over to a standard value map.
  ValueToValueMapTy VM;
  for (auto I = GVMap.begin(), E = GVMap.end(); I != E; ++I)
    VM[I->first] = I->second;

  // Walk through the metadata section and update the debug information
  // associated with the global variables in the default address space.
  for (NamedMDNode &I : M.named_metadata()) {
    remapNamedMDNode(VM, &I);
  }

  // Walk through the global variable  initializers, and replace any use of
  // original global variables in GVMap with a use of the corresponding copies
  // in GVMap.  The copies need to be bitcast to the original global variable
  // types, as we cannot use cvta in global variable initializers.
  for (GVMapTy::iterator I = GVMap.begin(), E = GVMap.end(); I != E;) {
    GlobalVariable *GV = I->first;
    GlobalVariable *NewGV = I->second;

    // Remove GV from the map so that it can be RAUWed.  Note that
    // DenseMap::erase() won't invalidate any iterators but this one.
    auto Next = std::next(I);
    GVMap.erase(I);
    I = Next;

    Constant *BitCastNewGV = ConstantExpr::getPointerCast(NewGV, GV->getType());
    // At this point, the remaining uses of GV should be found only in global
    // variable initializers, as other uses have been already been removed
    // while walking through the instructions in function definitions.
    GV->replaceAllUsesWith(BitCastNewGV);
    std::string Name = GV->getName();
    GV->eraseFromParent();
    NewGV->setName(Name);
  }
  assert(GVMap.empty() && "Expected it to be empty by now");

  return true;
}
Beispiel #11
0
bool LoaderPass::runOnModule(Module &M) {
  ProfileInfoLoader PIL("profile-loader", Filename, M);

  EdgeInformation.clear();
  std::vector<unsigned> Counters = PIL.getRawEdgeCounts();
  if (Counters.size() > 0) {
    ReadCount = 0;
    for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
      if (F->isDeclaration()) continue;
      DEBUG(dbgs()<<"Working on "<<F->getNameStr()<<"\n");
      readEdge(getEdge(0,&F->getEntryBlock()), Counters);
      for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
        TerminatorInst *TI = BB->getTerminator();
        for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) {
          readEdge(getEdge(BB,TI->getSuccessor(s)), Counters);
        }
      }
    }
    if (ReadCount != Counters.size()) {
      errs() << "WARNING: profile information is inconsistent with "
             << "the current program!\n";
    }
    NumEdgesRead = ReadCount;
  }

  Counters = PIL.getRawOptimalEdgeCounts();
  if (Counters.size() > 0) {
    ReadCount = 0;
    for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
      if (F->isDeclaration()) continue;
      DEBUG(dbgs()<<"Working on "<<F->getNameStr()<<"\n");
      readEdge(getEdge(0,&F->getEntryBlock()), Counters);
      for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
        TerminatorInst *TI = BB->getTerminator();
        if (TI->getNumSuccessors() == 0) {
          readEdge(getEdge(BB,0), Counters);
        }
        for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) {
          readEdge(getEdge(BB,TI->getSuccessor(s)), Counters);
        }
      }
      while (SpanningTree.size() > 0) {

        unsigned size = SpanningTree.size();

        BBisUnvisited.clear();
        for (std::set<Edge>::iterator ei = SpanningTree.begin(),
             ee = SpanningTree.end(); ei != ee; ++ei) {
          BBisUnvisited.insert(ei->first);
          BBisUnvisited.insert(ei->second);
        }
        while (BBisUnvisited.size() > 0) {
          recurseBasicBlock(*BBisUnvisited.begin());
        }

        if (SpanningTree.size() == size) {
          DEBUG(dbgs()<<"{");
          for (std::set<Edge>::iterator ei = SpanningTree.begin(),
               ee = SpanningTree.end(); ei != ee; ++ei) {
            DEBUG(dbgs()<< *ei <<",");
          }
          assert(0 && "No edge calculated!");
        }

      }
    }
    if (ReadCount != Counters.size()) {
      errs() << "WARNING: profile information is inconsistent with "
             << "the current program!\n";
    }
    NumEdgesRead = ReadCount;
  }

  BlockInformation.clear();
  Counters = PIL.getRawBlockCounts();
  if (Counters.size() > 0) {
    ReadCount = 0;
    for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
      if (F->isDeclaration()) continue;
      for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
        if (ReadCount < Counters.size())
          // Here the data realm changes from the unsigned of the file to the
          // double of the ProfileInfo. This conversion is save because we know
          // that everything thats representable in unsinged is also
          // representable in double.
          BlockInformation[F][BB] = (double)Counters[ReadCount++];
    }
    if (ReadCount != Counters.size()) {
      errs() << "WARNING: profile information is inconsistent with "
             << "the current program!\n";
    }
  }

  FunctionInformation.clear();
  Counters = PIL.getRawFunctionCounts();
  if (Counters.size() > 0) {
    ReadCount = 0;
    for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
      if (F->isDeclaration()) continue;
      if (ReadCount < Counters.size())
        // Here the data realm changes from the unsigned of the file to the
        // double of the ProfileInfo. This conversion is save because we know
        // that everything thats representable in unsinged is also
        // representable in double.
        FunctionInformation[F] = (double)Counters[ReadCount++];
    }
    if (ReadCount != Counters.size()) {
      errs() << "WARNING: profile information is inconsistent with "
             << "the current program!\n";
    }
  }

  return false;
}
Beispiel #12
0
//
// Method: runOnModule()
//
// Description:
//  Entry point for this LLVM pass.
//  Clone functions that take LoadInsts as arguments
//
// Inputs:
//  M - A reference to the LLVM module to transform
//
// Outputs:
//  M - The transformed LLVM module.
//
// Return value:
//  true  - The module was modified.
//  false - The module was not modified.
//
bool LoadArgs::runOnModule(Module& M) {
  std::map<std::pair<Function*, const Type * > , Function* > fnCache;
  bool changed;
  do { 
    changed = false;
    for (Module::iterator Func = M.begin(); Func != M.end(); ++Func) {
      for (Function::iterator B = Func->begin(), FE = Func->end(); B != FE; ++B) {
        for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) {
          CallInst *CI = dyn_cast<CallInst>(I++);
          if(!CI)
            continue;

          if(CI->hasByValArgument())
            continue;
          // if the CallInst calls a function, that is externally defined,
          // or might be changed, ignore this call site.
          Function *F = CI->getCalledFunction();
          if (!F || (F->isDeclaration() || F->mayBeOverridden())) 
            continue;
          if(F->hasStructRetAttr())
            continue;
          if(F->isVarArg())
            continue;

          // find the argument we must replace
          Function::arg_iterator ai = F->arg_begin(), ae = F->arg_end();
          unsigned argNum = 0;
          for(; argNum < CI->getNumArgOperands();argNum++, ++ai) {
            // do not care about dead arguments
            if(ai->use_empty())
              continue;
            if(F->getAttributes().getParamAttributes(argNum).hasAttrSomewhere(Attribute::SExt) ||
               F->getAttributes().getParamAttributes(argNum).hasAttrSomewhere(Attribute::ZExt))
              continue;
            if (isa<LoadInst>(CI->getArgOperand(argNum)))
              break;
          }

          // if no argument was a GEP operator to be changed 
          if(ai == ae)
            continue;

          LoadInst *LI = dyn_cast<LoadInst>(CI->getArgOperand(argNum));
          Instruction * InsertPt = &(Func->getEntryBlock().front());
          AllocaInst *NewVal = new AllocaInst(LI->getType(), "",InsertPt);

          StoreInst *Copy = new StoreInst(LI, NewVal);
          Copy->insertAfter(LI);
          /*if(LI->getParent() != CI->getParent())
            continue;
          // Also check that there is no store after the load.
          // TODO: Check if the load/store do not alias.
          BasicBlock::iterator bii = LI->getParent()->begin();
          Instruction *BII = bii;
          while(BII != LI) {
            ++bii;
            BII = bii;
          }
          while(BII != CI) {
            if(isa<StoreInst>(BII))
              break;
            ++bii;
            BII = bii;
          }
          if(isa<StoreInst>(bii)){
            continue;
          }*/

          // Construct the new Type
          // Appends the struct Type at the beginning
          std::vector<Type*>TP;
          for(unsigned c = 0; c < CI->getNumArgOperands();c++) {
            if(c == argNum)
              TP.push_back(LI->getPointerOperand()->getType());
            TP.push_back(CI->getArgOperand(c)->getType());
          }

          //return type is same as that of original instruction
          FunctionType *NewFTy = FunctionType::get(CI->getType(), TP, false);
          numSimplified++;
          //if(numSimplified > 1000)
          //return true;

          Function *NewF;
          std::map<std::pair<Function*, const Type* > , Function* >::iterator Test;
          Test = fnCache.find(std::make_pair(F, NewFTy));
          if(Test != fnCache.end()) {
            NewF = Test->second;
          } else {
            NewF = Function::Create(NewFTy,
                                    GlobalValue::InternalLinkage,
                                    F->getName().str() + ".TEST",
                                    &M);

            fnCache[std::make_pair(F, NewFTy)] = NewF;
            Function::arg_iterator NI = NewF->arg_begin();

            ValueToValueMapTy ValueMap;

            unsigned count = 0;
            for (Function::arg_iterator II = F->arg_begin(); NI != NewF->arg_end(); ++count, ++NI) {
              if(count == argNum) {
                NI->setName("LDarg");
                continue;
              }
              ValueMap[II] = NI;
              NI->setName(II->getName());
              NI->addAttr(F->getAttributes().getParamAttributes(II->getArgNo() + 1));
              ++II;
            }
            // Perform the cloning.
            SmallVector<ReturnInst*,100> Returns;
            CloneFunctionInto(NewF, F, ValueMap, false, Returns);
            std::vector<Value*> fargs;
            for(Function::arg_iterator ai = NewF->arg_begin(), 
                ae= NewF->arg_end(); ai != ae; ++ai) {
              fargs.push_back(ai);
            }

            NewF->setAttributes(NewF->getAttributes().addAttributes(
                F->getContext(), 0, F->getAttributes().getRetAttributes()));
            NewF->setAttributes(NewF->getAttributes().addAttributes(
                F->getContext(), ~0, F->getAttributes().getFnAttributes()));
            //Get the point to insert the GEP instr.
            Instruction *InsertPoint;
            for (BasicBlock::iterator insrt = NewF->front().begin(); isa<AllocaInst>(InsertPoint = insrt); ++insrt) {;}
            LoadInst *LI_new = new LoadInst(fargs.at(argNum), "", InsertPoint);
            fargs.at(argNum+1)->replaceAllUsesWith(LI_new);
          }
          
          //this does not seem to be a good idea
          AttributeSet NewCallPAL=AttributeSet();
	  
          // Get the initial attributes of the call
          AttributeSet CallPAL = CI->getAttributes();
          AttributeSet RAttrs = CallPAL.getRetAttributes();
          AttributeSet FnAttrs = CallPAL.getFnAttributes();
          if (!RAttrs.isEmpty())
            NewCallPAL=NewCallPAL.addAttributes(F->getContext(),0, RAttrs);

          SmallVector<Value*, 8> Args;
          for(unsigned j =0;j<CI->getNumArgOperands();j++) {
            if(j == argNum) {
              Args.push_back(NewVal);
            }
            Args.push_back(CI->getArgOperand(j));
            // position in the NewCallPAL
            AttributeSet Attrs = CallPAL.getParamAttributes(j+1);
            if (!Attrs.isEmpty())
              NewCallPAL=NewCallPAL.addAttributes(F->getContext(),Args.size(), Attrs);
          }
          // Create the new attributes vec.
          if (!FnAttrs.isEmpty())
            NewCallPAL=NewCallPAL.addAttributes(F->getContext(),~0, FnAttrs);

          CallInst *CallI = CallInst::Create(NewF,Args,"", CI);
          CallI->setCallingConv(CI->getCallingConv());
          CallI->setAttributes(NewCallPAL);
          CI->replaceAllUsesWith(CallI);
          CI->eraseFromParent();
          changed = true;
        }
      }
    }
  } while(changed);
  return true;
}
bool LoaderPass::runOnModule(Module &M) {
    ProfileInfoLoader PIL("profile-loader", Filename, M);

    EdgeInformation.clear();
    std::vector<unsigned> ECs = PIL.getRawEdgeCounts();
    if (ECs.size() > 0) {
        unsigned ei = 0;
        for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
            if (F->isDeclaration()) continue;
            if (ei < ECs.size())
                EdgeInformation[F][ProfileInfo::getEdge(0, &F->getEntryBlock())] +=
                    ECs[ei++];
            for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
                // Okay, we have to add a counter of each outgoing edge.  If the
                // outgoing edge is not critical don't split it, just insert the counter
                // in the source or destination of the edge.
                TerminatorInst *TI = BB->getTerminator();
                for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) {
                    if (ei < ECs.size())
                        EdgeInformation[F][ProfileInfo::getEdge(BB, TI->getSuccessor(s))] +=
                            ECs[ei++];
                }
            }
        }
        if (ei != ECs.size()) {
            cerr << "WARNING: profile information is inconsistent with "
                 << "the current program!\n";
        }
    }

    BlockInformation.clear();
    std::vector<unsigned> BCs = PIL.getRawBlockCounts();
    if (BCs.size() > 0) {
        unsigned bi = 0;
        for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
            if (F->isDeclaration()) continue;
            for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
                if (bi < BCs.size())
                    BlockInformation[F][BB] = BCs[bi++];
        }
        if (bi != BCs.size()) {
            cerr << "WARNING: profile information is inconsistent with "
                 << "the current program!\n";
        }
    }

    FunctionInformation.clear();
    std::vector<unsigned> FCs = PIL.getRawFunctionCounts();
    if (FCs.size() > 0) {
        unsigned fi = 0;
        for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
            if (F->isDeclaration()) continue;
            if (fi < FCs.size())
                FunctionInformation[F] = FCs[fi++];
        }
        if (fi != FCs.size()) {
            cerr << "WARNING: profile information is inconsistent with "
                 << "the current program!\n";
        }
    }

    return false;
}