Пример #1
0
  /// Prints top stacks from looking at all the leaves and ignoring thread IDs.
  /// Stacks that consist of the same function IDs but were called in different
  /// thread IDs are not considered unique in this printout.
  void printIgnoringThreads(raw_ostream &OS, FuncIdConversionHelper &FN) {
    RootVector RootValues;

    // Function to pull the values out of a map iterator.
    using RootsType = decltype(Roots.begin())::value_type;
    auto MapValueFn = [](const RootsType &Value) { return Value.second; };

    for (const auto &RootNodeRange :
         make_range(map_iterator(Roots.begin(), MapValueFn),
                    map_iterator(Roots.end(), MapValueFn))) {
      for (auto *RootNode : RootNodeRange)
        RootValues.push_back(RootNode);
    }

    print(OS, FN, RootValues);
  }
Пример #2
0
/// GetSortedStubs - Return the entries from a DenseMap in a deterministic
/// sorted orer.
MachineModuleInfoImpl::SymbolListTy
MachineModuleInfoImpl::GetSortedStubs(const DenseMap<MCSymbol*,
                                      MachineModuleInfoImpl::StubValueTy>&Map) {
  MachineModuleInfoImpl::SymbolListTy List(Map.begin(), Map.end());

  if (!List.empty())
    qsort(&List[0], List.size(), sizeof(List[0]), SortSymbolPair);
  return List;
}
Пример #3
0
  ~MMIAddrLabelMap() {
    assert(DeletedAddrLabelsNeedingEmission.empty() &&
           "Some labels for deleted blocks never got emitted");

    // Deallocate any of the 'list of symbols' case.
    for (DenseMap<AssertingVH<BasicBlock>, AddrLabelSymEntry>::iterator
         I = AddrLabelSymbols.begin(), E = AddrLabelSymbols.end(); I != E; ++I)
      if (I->second.Symbols.is<std::vector<MCSymbol*>*>())
        delete I->second.Symbols.get<std::vector<MCSymbol*>*>();
  }
Пример #4
0
static bool equals(const Function *F, const Function *G) {
  // We need to recheck everything, but check the things that weren't included
  // in the hash first.

  if (F->getAttributes() != G->getAttributes())
    return false;

  if (F->hasGC() != G->hasGC())
    return false;

  if (F->hasGC() && F->getGC() != G->getGC())
    return false;

  if (F->hasSection() != G->hasSection())
    return false;

  if (F->hasSection() && F->getSection() != G->getSection())
    return false;

  if (F->isVarArg() != G->isVarArg())
    return false;

  // TODO: if it's internal and only used in direct calls, we could handle this
  // case too.
  if (F->getCallingConv() != G->getCallingConv())
    return false;

  if (!isEquivalentType(F->getFunctionType(), G->getFunctionType()))
    return false;

  DenseMap<const Value *, const Value *> ValueMap;
  DenseMap<const Value *, const Value *> SpeculationMap;
  ValueMap[F] = G;

  assert(F->arg_size() == G->arg_size() &&
         "Identical functions have a different number of args.");

  for (Function::const_arg_iterator fi = F->arg_begin(), gi = G->arg_begin(),
         fe = F->arg_end(); fi != fe; ++fi, ++gi)
    ValueMap[fi] = gi;

  if (!equals(&F->getEntryBlock(), &G->getEntryBlock(), ValueMap,
              SpeculationMap))
    return false;

  for (DenseMap<const Value *, const Value *>::iterator
         I = SpeculationMap.begin(), E = SpeculationMap.end(); I != E; ++I) {
    if (ValueMap[I->first] != I->second)
      return false;
  }

  return true;
}
Пример #5
0
void ReplaceCallExpr::sortParmRefsByOffs(const char *StartBuf,
       DenseMap<const DeclRefExpr *, std::string> &ParmRefToStrMap,
       std::vector< std::pair<const DeclRefExpr *, int> > &SortedParmRefs)
{
  for(DenseMap<const DeclRefExpr *, std::string>::iterator
      I = ParmRefToStrMap.begin(), E = ParmRefToStrMap.end(); I != E; ++I) {

    const DeclRefExpr *ParmRef = (*I).first;
    SourceLocation ParmRefLocStart = ParmRef->getLocStart();
    const char *ParmRefStartBuf =
      SrcManager->getCharacterData(ParmRefLocStart);

    int Off = ParmRefStartBuf - StartBuf;
    TransAssert((Off >= 0) && "Bad Offset!");
    insertParmRef(SortedParmRefs, ParmRef, Off);
  }
}
Пример #6
0
/*
 *  When phis are created, only the sigma and phi operands are inserted into them. Thus, we need to insert V, for which sigmas and phis were created, as incoming value of all
 *  incoming edges that still haven't an operand associated for them
 */
void vSSA::populatePhis(SmallVector<PHINode*, 25> &vssaphi_created, Value *V)
{
	// If any vSSA_PHI was created, iterate over the predecessors of vSSA_PHIs to insert V as an operand from the branches where sigma was not created
	for (SmallVectorImpl<PHINode*>::iterator vit = vssaphi_created.begin(), vend = vssaphi_created.end(); vit != vend; ++vit) {
		PHINode *vssaphi = *vit;
		BasicBlock *BB_parent = vssaphi->getParent();
		
		DenseMap<BasicBlock*, unsigned> howManyTimesIsPred;
		
		// Get how many times each basicblock is predecessor of BB_parent
		for (pred_iterator PI = pred_begin(BB_parent), PE = pred_end(BB_parent); PI != PE; ++PI) {
			BasicBlock *predBB = *PI;
			
			DenseMap<BasicBlock*, unsigned>::iterator mit = howManyTimesIsPred.find(predBB);
			
			if (mit == howManyTimesIsPred.end()) {
				howManyTimesIsPred.insert(std::make_pair(predBB, 1));
			}
			else {
				++mit->second;
			}
		}
		
		unsigned i, e;
		
		// If a predecessor already has incoming values in the vSSA_phi, we don't count them
		for (i = 0, e = vssaphi->getNumIncomingValues(); i < e; ++i) {
			--howManyTimesIsPred[vssaphi->getIncomingBlock(i)];
		}
		
		// Finally, add V as incoming value of predBB as many as necessary
		for (DenseMap<BasicBlock*, unsigned>::iterator mit = howManyTimesIsPred.begin(), mend = howManyTimesIsPred.end(); mit != mend; ++mit) {
			unsigned count;
			BasicBlock *predBB = mit->first;
			
			for (count = mit->second; count > 0; --count) {
				vssaphi->addIncoming(V, predBB);
			}
		}
		
		howManyTimesIsPred.clear();
	}
}
/// getNonLocalDependency - Fills the passed-in map with the non-local 
/// dependencies of the queries.  The map will contain NonLocal for
/// blocks between the query and its dependencies.
void MemoryDependenceAnalysis::getNonLocalDependency(Instruction* query,
                                         DenseMap<BasicBlock*, Value*>& resp) {
  if (depGraphNonLocal.count(query)) {
    DenseMap<BasicBlock*, Value*>& cached = depGraphNonLocal[query];
    NumCacheNonlocal++;
    
    SmallVector<BasicBlock*, 4> dirtied;
    for (DenseMap<BasicBlock*, Value*>::iterator I = cached.begin(),
         E = cached.end(); I != E; ++I)
      if (I->second == Dirty)
        dirtied.push_back(I->first);
    
    for (SmallVector<BasicBlock*, 4>::iterator I = dirtied.begin(),
         E = dirtied.end(); I != E; ++I) {
      Instruction* localDep = getDependency(query, 0, *I);
      if (localDep != NonLocal)
        cached[*I] = localDep;
      else {
        cached.erase(*I);
        nonLocalHelper(query, *I, cached);
      }
    }
    
    resp = cached;
    
    return;
  } else
    NumUncacheNonlocal++;
  
  // If not, go ahead and search for non-local deps.
  nonLocalHelper(query, query->getParent(), resp);
  
  // Update the non-local dependency cache
  for (DenseMap<BasicBlock*, Value*>::iterator I = resp.begin(), E = resp.end();
       I != E; ++I) {
    depGraphNonLocal[query].insert(*I);
    reverseDepNonLocal[I->second].insert(query);
  }
}
Пример #8
0
void StackColoring::remapInstructions(DenseMap<int, int> &SlotRemap) {
  unsigned FixedInstr = 0;
  unsigned FixedMemOp = 0;
  unsigned FixedDbg = 0;
  MachineModuleInfo *MMI = &MF->getMMI();

  // Remap debug information that refers to stack slots.
  MachineModuleInfo::VariableDbgInfoMapTy &VMap = MMI->getVariableDbgInfo();
  for (MachineModuleInfo::VariableDbgInfoMapTy::iterator VI = VMap.begin(),
       VE = VMap.end(); VI != VE; ++VI) {
    const MDNode *Var = VI->first;
    if (!Var) continue;
    std::pair<unsigned, DebugLoc> &VP = VI->second;
    if (SlotRemap.count(VP.first)) {
      DEBUG(dbgs()<<"Remapping debug info for ["<<Var->getName()<<"].\n");
      VP.first = SlotRemap[VP.first];
      FixedDbg++;
    }
  }

  // Keep a list of *allocas* which need to be remapped.
  DenseMap<const AllocaInst*, const AllocaInst*> Allocas;
  for (DenseMap<int, int>::const_iterator it = SlotRemap.begin(),
       e = SlotRemap.end(); it != e; ++it) {
    const AllocaInst *From = MFI->getObjectAllocation(it->first);
    const AllocaInst *To = MFI->getObjectAllocation(it->second);
    assert(To && From && "Invalid allocation object");
    Allocas[From] = To;
  }

  // Remap all instructions to the new stack slots.
  MachineFunction::iterator BB, BBE;
  MachineBasicBlock::iterator I, IE;
  for (BB = MF->begin(), BBE = MF->end(); BB != BBE; ++BB)
    for (I = BB->begin(), IE = BB->end(); I != IE; ++I) {

      // Skip lifetime markers. We'll remove them soon.
      if (I->getOpcode() == TargetOpcode::LIFETIME_START ||
          I->getOpcode() == TargetOpcode::LIFETIME_END)
        continue;

      // Update the MachineMemOperand to use the new alloca.
      for (MachineInstr::mmo_iterator MM = I->memoperands_begin(),
           E = I->memoperands_end(); MM != E; ++MM) {
        MachineMemOperand *MMO = *MM;

        const Value *V = MMO->getValue();

        if (!V)
          continue;

        const PseudoSourceValue *PSV = dyn_cast<const PseudoSourceValue>(V);
        if (PSV && PSV->isConstant(MFI))
          continue;

        // Climb up and find the original alloca.
        V = GetUnderlyingObject(V);
        // If we did not find one, or if the one that we found is not in our
        // map, then move on.
        if (!V || !isa<AllocaInst>(V)) {
          // Clear mem operand since we don't know for sure that it doesn't
          // alias a merged alloca.
          MMO->setValue(0);
          continue;
        }
        const AllocaInst *AI= cast<AllocaInst>(V);
        if (!Allocas.count(AI))
          continue;

        MMO->setValue(Allocas[AI]);
        FixedMemOp++;
      }

      // Update all of the machine instruction operands.
      for (unsigned i = 0 ; i <  I->getNumOperands(); ++i) {
        MachineOperand &MO = I->getOperand(i);

        if (!MO.isFI())
          continue;
        int FromSlot = MO.getIndex();

        // Don't touch arguments.
        if (FromSlot<0)
          continue;

        // Only look at mapped slots.
        if (!SlotRemap.count(FromSlot))
          continue;

        // In a debug build, check that the instruction that we are modifying is
        // inside the expected live range. If the instruction is not inside
        // the calculated range then it means that the alloca usage moved
        // outside of the lifetime markers, or that the user has a bug.
        // NOTE: Alloca address calculations which happen outside the lifetime
        // zone are are okay, despite the fact that we don't have a good way
        // for validating all of the usages of the calculation.
#ifndef NDEBUG
        bool TouchesMemory = I->mayLoad() || I->mayStore();
        // If we *don't* protect the user from escaped allocas, don't bother
        // validating the instructions.
        if (!I->isDebugValue() && TouchesMemory && ProtectFromEscapedAllocas) {
          SlotIndex Index = Indexes->getInstructionIndex(I);
          LiveInterval *Interval = Intervals[FromSlot];
          assert(Interval->find(Index) != Interval->end() &&
                 "Found instruction usage outside of live range.");
        }
#endif

        // Fix the machine instructions.
        int ToSlot = SlotRemap[FromSlot];
        MO.setIndex(ToSlot);
        FixedInstr++;
      }
    }

  DEBUG(dbgs()<<"Fixed "<<FixedMemOp<<" machine memory operands.\n");
  DEBUG(dbgs()<<"Fixed "<<FixedDbg<<" debug locations.\n");
  DEBUG(dbgs()<<"Fixed "<<FixedInstr<<" machine instructions.\n");
}
Пример #9
0
/// ComputeLocalLiveness - Computes liveness of registers within a basic
/// block, setting the killed/dead flags as appropriate.
void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) {
  MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
  // Keep track of the most recently seen previous use or def of each reg, 
  // so that we can update them with dead/kill markers.
  DenseMap<unsigned, std::pair<MachineInstr*, unsigned> > LastUseDef;
  for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
       I != E; ++I) {
    if (I->isDebugValue())
      continue;
    
    for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
      MachineOperand &MO = I->getOperand(i);
      // Uses don't trigger any flags, but we need to save
      // them for later.  Also, we have to process these
      // _before_ processing the defs, since an instr
      // uses regs before it defs them.
      if (!MO.isReg() || !MO.getReg() || !MO.isUse())
        continue;
      
      LastUseDef[MO.getReg()] = std::make_pair(I, i);
      
      if (TargetRegisterInfo::isVirtualRegister(MO.getReg())) continue;
      
      const unsigned *Aliases = TRI->getAliasSet(MO.getReg());
      if (Aliases == 0)
        continue;
      
      while (*Aliases) {
        DenseMap<unsigned, std::pair<MachineInstr*, unsigned> >::iterator
          alias = LastUseDef.find(*Aliases);
        
        if (alias != LastUseDef.end() && alias->second.first != I)
          LastUseDef[*Aliases] = std::make_pair(I, i);
        
        ++Aliases;
      }
    }
    
    for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
      MachineOperand &MO = I->getOperand(i);
      // Defs others than 2-addr redefs _do_ trigger flag changes:
      //   - A def followed by a def is dead
      //   - A use followed by a def is a kill
      if (!MO.isReg() || !MO.getReg() || !MO.isDef()) continue;
      
      DenseMap<unsigned, std::pair<MachineInstr*, unsigned> >::iterator
        last = LastUseDef.find(MO.getReg());
      if (last != LastUseDef.end()) {
        // Check if this is a two address instruction.  If so, then
        // the def does not kill the use.
        if (last->second.first == I &&
            I->isRegTiedToUseOperand(i))
          continue;
        
        MachineOperand &lastUD =
                    last->second.first->getOperand(last->second.second);
        if (lastUD.isDef())
          lastUD.setIsDead(true);
        else
          lastUD.setIsKill(true);
      }
      
      LastUseDef[MO.getReg()] = std::make_pair(I, i);
    }
  }
  
  // Live-out (of the function) registers contain return values of the function,
  // so we need to make sure they are alive at return time.
  MachineBasicBlock::iterator Ret = MBB.getFirstTerminator();
  bool BBEndsInReturn = (Ret != MBB.end() && Ret->getDesc().isReturn());

  if (BBEndsInReturn)
    for (MachineRegisterInfo::liveout_iterator
         I = MF->getRegInfo().liveout_begin(),
         E = MF->getRegInfo().liveout_end(); I != E; ++I)
      if (!Ret->readsRegister(*I)) {
        Ret->addOperand(MachineOperand::CreateReg(*I, false, true));
        LastUseDef[*I] = std::make_pair(Ret, Ret->getNumOperands()-1);
      }
  
  // Finally, loop over the final use/def of each reg 
  // in the block and determine if it is dead.
  for (DenseMap<unsigned, std::pair<MachineInstr*, unsigned> >::iterator
       I = LastUseDef.begin(), E = LastUseDef.end(); I != E; ++I) {
    MachineInstr *MI = I->second.first;
    unsigned idx = I->second.second;
    MachineOperand &MO = MI->getOperand(idx);
    
    bool isPhysReg = TargetRegisterInfo::isPhysicalRegister(MO.getReg());
    
    // A crude approximation of "live-out" calculation
    bool usedOutsideBlock = isPhysReg ? false :   
          UsedInMultipleBlocks.test(MO.getReg() -  
                                    TargetRegisterInfo::FirstVirtualRegister);

    // If the machine BB ends in a return instruction, then the value isn't used
    // outside of the BB.
    if (!isPhysReg && (!usedOutsideBlock || BBEndsInReturn)) {
      // DBG_VALUE complicates this:  if the only refs of a register outside
      // this block are DBG_VALUE, we can't keep the reg live just for that,
      // as it will cause the reg to be spilled at the end of this block when
      // it wouldn't have been otherwise.  Nullify the DBG_VALUEs when that
      // happens.
      bool UsedByDebugValueOnly = false;
      for (MachineRegisterInfo::reg_iterator UI = MRI.reg_begin(MO.getReg()),
             UE = MRI.reg_end(); UI != UE; ++UI) {
        // Two cases:
        // - used in another block
        // - used in the same block before it is defined (loop)
        if (UI->getParent() == &MBB &&
            !(MO.isDef() && UI.getOperand().isUse() && precedes(&*UI, MI)))
          continue;
        
        if (UI->isDebugValue()) {
          UsedByDebugValueOnly = true;
          continue;
        }

        // A non-DBG_VALUE use means we can leave DBG_VALUE uses alone.
        UsedInMultipleBlocks.set(MO.getReg() - 
                                 TargetRegisterInfo::FirstVirtualRegister);
        usedOutsideBlock = true;
        UsedByDebugValueOnly = false;
        break;
      }

      if (UsedByDebugValueOnly)
        for (MachineRegisterInfo::reg_iterator UI = MRI.reg_begin(MO.getReg()),
             UE = MRI.reg_end(); UI != UE; ++UI)
          if (UI->isDebugValue() &&
              (UI->getParent() != &MBB ||
               (MO.isDef() && precedes(&*UI, MI))))
            UI.getOperand().setReg(0U);
    }
  
    // Physical registers and those that are not live-out of the block are
    // killed/dead at their last use/def within this block.
    if (isPhysReg || !usedOutsideBlock || BBEndsInReturn) {
      if (MO.isUse()) {
        // Don't mark uses that are tied to defs as kills.
        if (!MI->isRegTiedToDefOperand(idx))
          MO.setIsKill(true);
      } else {
        MO.setIsDead(true);
      }
    }
  }
}
/// nonLocalHelper - Private helper used to calculate non-local dependencies
/// by doing DFS on the predecessors of a block to find its dependencies
void MemoryDependenceAnalysis::nonLocalHelper(Instruction* query,
                                              BasicBlock* block,
                                         DenseMap<BasicBlock*, Value*>& resp) {
  // Set of blocks that we've already visited in our DFS
  SmallPtrSet<BasicBlock*, 4> visited;
  // If we're updating a dirtied cache entry, we don't need to reprocess
  // already computed entries.
  for (DenseMap<BasicBlock*, Value*>::iterator I = resp.begin(), 
       E = resp.end(); I != E; ++I)
    if (I->second != Dirty)
      visited.insert(I->first);
  
  // Current stack of the DFS
  SmallVector<BasicBlock*, 4> stack;
  for (pred_iterator PI = pred_begin(block), PE = pred_end(block);
       PI != PE; ++PI)
    stack.push_back(*PI);
  
  // Do a basic DFS
  while (!stack.empty()) {
    BasicBlock* BB = stack.back();
    
    // If we've already visited this block, no need to revist
    if (visited.count(BB)) {
      stack.pop_back();
      continue;
    }
    
    // If we find a new block with a local dependency for query,
    // then we insert the new dependency and backtrack.
    if (BB != block) {
      visited.insert(BB);
      
      Instruction* localDep = getDependency(query, 0, BB);
      if (localDep != NonLocal) {
        resp.insert(std::make_pair(BB, localDep));
        stack.pop_back();
        
        continue;
      }
    // If we re-encounter the starting block, we still need to search it
    // because there might be a dependency in the starting block AFTER
    // the position of the query.  This is necessary to get loops right.
    } else if (BB == block) {
      visited.insert(BB);
      
      Instruction* localDep = getDependency(query, 0, BB);
      if (localDep != query)
        resp.insert(std::make_pair(BB, localDep));
      
      stack.pop_back();
      
      continue;
    }
    
    // If we didn't find anything, recurse on the precessors of this block
    // Only do this for blocks with a small number of predecessors.
    bool predOnStack = false;
    bool inserted = false;
    if (std::distance(pred_begin(BB), pred_end(BB)) <= PredLimit) { 
      for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB);
           PI != PE; ++PI)
        if (!visited.count(*PI)) {
          stack.push_back(*PI);
          inserted = true;
        } else
          predOnStack = true;
    }
    
    // If we inserted a new predecessor, then we'll come back to this block
    if (inserted)
      continue;
    // If we didn't insert because we have no predecessors, then this
    // query has no dependency at all.
    else if (!inserted && !predOnStack) {
      resp.insert(std::make_pair(BB, None));
    // If we didn't insert because our predecessors are already on the stack,
    // then we might still have a dependency, but it will be discovered during
    // backtracking.
    } else if (!inserted && predOnStack){
      resp.insert(std::make_pair(BB, NonLocal));
    }
    
    stack.pop_back();
  }
}
Пример #11
0
/*
 * Rewrite OpenMP call sites and their associated kernel functions  -- the folloiwng pattern
   call void @GOMP_parallel_start(void (i8*)* @_Z20initialize_variablesiPfS_.omp_fn.4, i8* %.omp_data_o.5571, i32 0) nounwind
  call void @_Z20initialize_variablesiPfS_.omp_fn.4(i8* %.omp_data_o.5571) nounwind
  call void @GOMP_parallel_end() nounwind
 */
void HeteroOMPTransform::rewrite_omp_call_sites(Module &M) {
	SmallVector<Instruction *, 16> toDelete;
	DenseMap<Value *, Value *> ValueMap;
	
	for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I){
		if (!I->isDeclaration()) {
			
			for (Function::iterator BBI = I->begin(), BBE = I->end(); BBI != BBE; ++BBI) {
				bool match = false;
				for (BasicBlock::iterator INSNI = BBI->begin(), INSNE = BBI->end(); INSNI != INSNE; ++INSNI) {
					if (isa<CallInst>(INSNI)) {
						CallSite CI(cast<Instruction>(INSNI));
						if (CI.getCalledFunction() != NULL){ 
							string called_func_name = CI.getCalledFunction()->getName();
							if (called_func_name == OMP_PARALLEL_START_NAME && CI.arg_size() == 3) {
								// change alloc to malloc_shared
								// %5 = call i8* @_Z13malloc_sharedm(i64 20)       ; <i8*> [#uses=5]
								// %6 = bitcast i8* %5 to float*                   ; <float*> [#uses=2]
								AllocaInst *AllocCall;
								Value *arg_0 = CI.getArgument(0); // function
								Value *arg_1 = CI.getArgument(1);  // context
								Value *loop_ub = NULL;
								Function *function;
								BitCastInst* BCI;
								Function *kernel_function;
								BasicBlock::iterator iI(*INSNI); 
								//BasicBlock::iterator iJ = iI+1; 
								iI++; iI++;
								//BasicBlock::iterator iK = iI;  
								CallInst /**next,*/ *next_next; 
								if (arg_0 != NULL && arg_1 != NULL /*&& (next = dyn_cast<CallInst>(*iJ))*/ 
									&& (next_next = dyn_cast<CallInst>(iI)) && (next_next->getCalledFunction() != NULL) 
									&& (next_next->getCalledFunction()->getName() == OMP_PARALLEL_END_NAME)
									&& (BCI = dyn_cast<BitCastInst>(arg_1)) && (AllocCall = dyn_cast<AllocaInst>(BCI->getOperand(0))) 
									&& (function = dyn_cast<Function>(arg_0)) && (loop_ub = find_loop_upper_bound (AllocCall)) 
									&& (kernel_function=convert_to_kernel_function (M, function))){
									
										SmallVector<Value*, 16> Args;
										Args.push_back(AllocCall->getArraySize());
										Instruction *MallocCall = CallInst::Create(mallocFnTy, Args, "", AllocCall);
										CastInst *MallocCast = CastInst::Create(Instruction::BitCast, MallocCall, AllocCall->getType(), "", AllocCall);
										ValueMap[AllocCall] = MallocCast;
										//AllocCall->replaceAllUsesWith(MallocCall);
										// Add offload function
										Args.clear();
										Args.push_back(loop_ub);
										Args.push_back(BCI);
										Args.push_back(kernel_function);
										if (offloadFnTy == NULL) {
											init_offload_type(M, kernel_function);
										}
										
										Instruction *call = CallInst::Create(offloadFnTy, Args, "", INSNI);
										
										if (find(toDelete.begin(), toDelete.end(), AllocCall) == toDelete.end()){
											toDelete.push_back(AllocCall);
										}
										toDelete.push_back(&(*INSNI));
										match = true;
								}
							}
							else if (called_func_name == OMP_PARALLEL_END_NAME && CI.arg_size() == 0 && match) {
								toDelete.push_back(&(*INSNI));
								match = false;
							}
							else if (match) {
								toDelete.push_back(&(*INSNI));
							}
						}
					}
				}
			}
		}

	}

	/* Replace AllocCalls by MallocCalls */
	for(DenseMap<Value *, Value *>::iterator I = ValueMap.begin(), E = ValueMap.end(); I != E; I++) {
		I->first->replaceAllUsesWith(I->second);
	}

	/* delete the instructions for get_omp_num_thread and get_omp_thread_num */
	while(!toDelete.empty()) {
		Instruction *g = toDelete.back();
		toDelete.pop_back();
		g->eraseFromParent();
	}

}
Пример #12
0
void StackColoring::remapInstructions(DenseMap<int, int> &SlotRemap) {
  unsigned FixedInstr = 0;
  unsigned FixedMemOp = 0;
  unsigned FixedDbg = 0;
  MachineModuleInfo *MMI = &MF->getMMI();

  // Remap debug information that refers to stack slots.
  MachineModuleInfo::VariableDbgInfoMapTy &VMap = MMI->getVariableDbgInfo();
  for (MachineModuleInfo::VariableDbgInfoMapTy::iterator VI = VMap.begin(),
       VE = VMap.end(); VI != VE; ++VI) {
    const MDNode *Var = VI->first;
    if (!Var) continue;
    std::pair<unsigned, DebugLoc> &VP = VI->second;
    if (SlotRemap.count(VP.first)) {
      DEBUG(dbgs()<<"Remapping debug info for ["<<Var->getName()<<"].\n");
      VP.first = SlotRemap[VP.first];
      FixedDbg++;
    }
  }

  // Keep a list of *allocas* which need to be remapped.
  DenseMap<const Value*, const Value*> Allocas;
  for (DenseMap<int, int>::iterator it = SlotRemap.begin(),
       e = SlotRemap.end(); it != e; ++it) {
    const Value *From = MFI->getObjectAllocation(it->first);
    const Value *To = MFI->getObjectAllocation(it->second);
    assert(To && From && "Invalid allocation object");
    Allocas[From] = To;
  }

  // Remap all instructions to the new stack slots.
  MachineFunction::iterator BB, BBE;
  MachineBasicBlock::iterator I, IE;
  for (BB = MF->begin(), BBE = MF->end(); BB != BBE; ++BB)
    for (I = BB->begin(), IE = BB->end(); I != IE; ++I) {

      // Skip lifetime markers. We'll remove them soon.
      if (I->getOpcode() == TargetOpcode::LIFETIME_START ||
          I->getOpcode() == TargetOpcode::LIFETIME_END)
        continue;

      // Update the MachineMemOperand to use the new alloca.
      for (MachineInstr::mmo_iterator MM = I->memoperands_begin(),
           E = I->memoperands_end(); MM != E; ++MM) {
        MachineMemOperand *MMO = *MM;

        const Value *V = MMO->getValue();

        if (!V)
          continue;

        // Climb up and find the original alloca.
        V = GetUnderlyingObject(V);
        // If we did not find one, or if the one that we found is not in our
        // map, then move on.
        if (!V || !Allocas.count(V))
          continue;

        MMO->setValue(Allocas[V]);
        FixedMemOp++;
      }

      // Update all of the machine instruction operands.
      for (unsigned i = 0 ; i <  I->getNumOperands(); ++i) {
        MachineOperand &MO = I->getOperand(i);

        if (!MO.isFI())
          continue;
        int FromSlot = MO.getIndex();

        // Don't touch arguments.
        if (FromSlot<0)
          continue;

        // Only look at mapped slots.
        if (!SlotRemap.count(FromSlot))
          continue;

        // In a debug build, check that the instruction that we are modifying is
        // inside the expected live range. If the instruction is not inside
        // the calculated range then it means that the alloca usage moved
        // outside of the lifetime markers.
#ifndef NDEBUG
        SlotIndex Index = Indexes->getInstructionIndex(I);
        LiveInterval* Interval = Intervals[FromSlot];
        assert(Interval->find(Index) != Interval->end() &&
               "Found instruction usage outside of live range.");
#endif

        // Fix the machine instructions.
        int ToSlot = SlotRemap[FromSlot];
        MO.setIndex(ToSlot);
        FixedInstr++;
      }
    }

  DEBUG(dbgs()<<"Fixed "<<FixedMemOp<<" machine memory operands.\n");
  DEBUG(dbgs()<<"Fixed "<<FixedDbg<<" debug locations.\n");
  DEBUG(dbgs()<<"Fixed "<<FixedInstr<<" machine instructions.\n");
}