Example #1
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");
}
Example #2
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");
}