Beispiel #1
0
bool UnpackMachineBundles::runOnMachineFunction(MachineFunction &MF) {
  bool Changed = false;
  for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
    MachineBasicBlock *MBB = &*I;

    for (MachineBasicBlock::instr_iterator MII = MBB->instr_begin(),
           MIE = MBB->instr_end(); MII != MIE; ) {
      MachineInstr *MI = &*MII;

      // Remove BUNDLE instruction and the InsideBundle flags from bundled
      // instructions.
      if (MI->isBundle()) {
        while (++MII != MIE && MII->isBundledWithPred()) {
          MII->unbundleFromPred();
          for (unsigned i = 0, e = MII->getNumOperands(); i != e; ++i) {
            MachineOperand &MO = MII->getOperand(i);
            if (MO.isReg() && MO.isInternalRead())
              MO.setIsInternalRead(false);
          }
        }
        MI->eraseFromParent();

        Changed = true;
        continue;
      }

      ++MII;
    }
  }

  return Changed;
}
 ClauseFile
 MakeALUClause(MachineBasicBlock &MBB, MachineBasicBlock::iterator &I)
     const {
   MachineBasicBlock::iterator ClauseHead = I;
   std::vector<MachineInstr *> ClauseContent;
   I++;
   for (MachineBasicBlock::instr_iterator E = MBB.instr_end(); I != E;) {
     if (IsTrivialInst(I)) {
       ++I;
       continue;
     }
     if (!I->isBundle() && !TII->isALUInstr(I->getOpcode()))
       break;
     std::vector<int64_t> Literals;
     if (I->isBundle()) {
       MachineInstr *DeleteMI = I;
       MachineBasicBlock::instr_iterator BI = I.getInstrIterator();
       while (++BI != E && BI->isBundledWithPred()) {
         BI->unbundleFromPred();
         for (unsigned i = 0, e = BI->getNumOperands(); i != e; ++i) {
           MachineOperand &MO = BI->getOperand(i);
           if (MO.isReg() && MO.isInternalRead())
             MO.setIsInternalRead(false);
         }
         getLiteral(BI, Literals);
         ClauseContent.push_back(BI);
       }
       I = BI;
       DeleteMI->eraseFromParent();
     } else {
       getLiteral(I, Literals);
       ClauseContent.push_back(I);
       I++;
     }
     for (unsigned i = 0, e = Literals.size(); i < e; i+=2) {
       unsigned literal0 = Literals[i];
       unsigned literal2 = (i + 1 < e)?Literals[i + 1]:0;
       MachineInstr *MILit = BuildMI(MBB, I, I->getDebugLoc(),
           TII->get(AMDGPU::LITERALS))
           .addImm(literal0)
           .addImm(literal2);
       ClauseContent.push_back(MILit);
     }
   }
   ClauseHead->getOperand(7).setImm(ClauseContent.size() - 1);
   return ClauseFile(ClauseHead, ClauseContent);
 }
bool Thumb2SizeReduce::ReduceMBB(MachineBasicBlock &MBB) {
  bool Modified = false;

  // Yes, CPSR could be livein.
  bool LiveCPSR = MBB.isLiveIn(ARM::CPSR);
  MachineInstr *BundleMI = 0;

  CPSRDef = 0;
  HighLatencyCPSR = false;

  // Check predecessors for the latest CPSRDef.
  for (MachineBasicBlock::pred_iterator
       I = MBB.pred_begin(), E = MBB.pred_end(); I != E; ++I) {
    const MBBInfo &PInfo = BlockInfo[(*I)->getNumber()];
    if (!PInfo.Visited) {
      // Since blocks are visited in RPO, this must be a back-edge.
      continue;
    }
    if (PInfo.HighLatencyCPSR) {
      HighLatencyCPSR = true;
      break;
    }
  }

  // If this BB loops back to itself, conservatively avoid narrowing the
  // first instruction that does partial flag update.
  bool IsSelfLoop = MBB.isSuccessor(&MBB);
  MachineBasicBlock::instr_iterator MII = MBB.instr_begin(),E = MBB.instr_end();
  MachineBasicBlock::instr_iterator NextMII;
  for (; MII != E; MII = NextMII) {
    NextMII = llvm::next(MII);

    MachineInstr *MI = &*MII;
    if (MI->isBundle()) {
      BundleMI = MI;
      continue;
    }
    if (MI->isDebugValue())
      continue;

    LiveCPSR = UpdateCPSRUse(*MI, LiveCPSR);

    // Does NextMII belong to the same bundle as MI?
    bool NextInSameBundle = NextMII != E && NextMII->isBundledWithPred();

    if (ReduceMI(MBB, MI, LiveCPSR, IsSelfLoop)) {
      Modified = true;
      MachineBasicBlock::instr_iterator I = prior(NextMII);
      MI = &*I;
      // Removing and reinserting the first instruction in a bundle will break
      // up the bundle. Fix the bundling if it was broken.
      if (NextInSameBundle && !NextMII->isBundledWithPred())
        NextMII->bundleWithPred();
    }

    if (!NextInSameBundle && MI->isInsideBundle()) {
      // FIXME: Since post-ra scheduler operates on bundles, the CPSR kill
      // marker is only on the BUNDLE instruction. Process the BUNDLE
      // instruction as we finish with the bundled instruction to work around
      // the inconsistency.
      if (BundleMI->killsRegister(ARM::CPSR))
        LiveCPSR = false;
      MachineOperand *MO = BundleMI->findRegisterDefOperand(ARM::CPSR);
      if (MO && !MO->isDead())
        LiveCPSR = true;
    }

    bool DefCPSR = false;
    LiveCPSR = UpdateCPSRDef(*MI, LiveCPSR, DefCPSR);
    if (MI->isCall()) {
      // Calls don't really set CPSR.
      CPSRDef = 0;
      HighLatencyCPSR = false;
      IsSelfLoop = false;
    } else if (DefCPSR) {
      // This is the last CPSR defining instruction.
      CPSRDef = MI;
      HighLatencyCPSR = isHighLatencyCPSR(CPSRDef);
      IsSelfLoop = false;
    }
  }

  MBBInfo &Info = BlockInfo[MBB.getNumber()];
  Info.HighLatencyCPSR = HighLatencyCPSR;
  Info.Visited = true;
  return Modified;
}