123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- //===--- ARMBasicBlockInfo.cpp - Utilities for block sizes ---------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #include "ARMBasicBlockInfo.h"
- #include "ARM.h"
- #include "ARMBaseInstrInfo.h"
- #include "ARMMachineFunctionInfo.h"
- #include "llvm/CodeGen/MachineBasicBlock.h"
- #include "llvm/CodeGen/MachineFunction.h"
- #include "llvm/CodeGen/MachineInstr.h"
- #include "llvm/CodeGen/TargetSubtargetInfo.h"
- #include "llvm/IR/GlobalVariable.h"
- #include "llvm/Support/Debug.h"
- #include <vector>
- #define DEBUG_TYPE "arm-bb-utils"
- using namespace llvm;
- namespace llvm {
- // mayOptimizeThumb2Instruction - Returns true if optimizeThumb2Instructions
- // below may shrink MI.
- static bool
- mayOptimizeThumb2Instruction(const MachineInstr *MI) {
- switch(MI->getOpcode()) {
- // optimizeThumb2Instructions.
- case ARM::t2LEApcrel:
- case ARM::t2LDRpci:
- // optimizeThumb2Branches.
- case ARM::t2B:
- case ARM::t2Bcc:
- case ARM::tBcc:
- // optimizeThumb2JumpTables.
- case ARM::t2BR_JT:
- case ARM::tBR_JTr:
- return true;
- }
- return false;
- }
- void ARMBasicBlockUtils::computeBlockSize(MachineBasicBlock *MBB) {
- LLVM_DEBUG(dbgs() << "computeBlockSize: " << MBB->getName() << "\n");
- BasicBlockInfo &BBI = BBInfo[MBB->getNumber()];
- BBI.Size = 0;
- BBI.Unalign = 0;
- BBI.PostAlign = Align(1);
- for (MachineInstr &I : *MBB) {
- BBI.Size += TII->getInstSizeInBytes(I);
- // For inline asm, getInstSizeInBytes returns a conservative estimate.
- // The actual size may be smaller, but still a multiple of the instr size.
- if (I.isInlineAsm())
- BBI.Unalign = isThumb ? 1 : 2;
- // Also consider instructions that may be shrunk later.
- else if (isThumb && mayOptimizeThumb2Instruction(&I))
- BBI.Unalign = 1;
- }
- // tBR_JTr contains a .align 2 directive.
- if (!MBB->empty() && MBB->back().getOpcode() == ARM::tBR_JTr) {
- BBI.PostAlign = Align(4);
- MBB->getParent()->ensureAlignment(Align(4));
- }
- }
- /// getOffsetOf - Return the current offset of the specified machine instruction
- /// from the start of the function. This offset changes as stuff is moved
- /// around inside the function.
- unsigned ARMBasicBlockUtils::getOffsetOf(MachineInstr *MI) const {
- const MachineBasicBlock *MBB = MI->getParent();
- // The offset is composed of two things: the sum of the sizes of all MBB's
- // before this instruction's block, and the offset from the start of the block
- // it is in.
- unsigned Offset = BBInfo[MBB->getNumber()].Offset;
- // Sum instructions before MI in MBB.
- for (MachineBasicBlock::const_iterator I = MBB->begin(); &*I != MI; ++I) {
- assert(I != MBB->end() && "Didn't find MI in its own basic block?");
- Offset += TII->getInstSizeInBytes(*I);
- }
- return Offset;
- }
- /// isBBInRange - Returns true if the distance between specific MI and
- /// specific BB can fit in MI's displacement field.
- bool ARMBasicBlockUtils::isBBInRange(MachineInstr *MI,
- MachineBasicBlock *DestBB,
- unsigned MaxDisp) const {
- unsigned PCAdj = isThumb ? 4 : 8;
- unsigned BrOffset = getOffsetOf(MI) + PCAdj;
- unsigned DestOffset = BBInfo[DestBB->getNumber()].Offset;
- LLVM_DEBUG(dbgs() << "Branch of destination " << printMBBReference(*DestBB)
- << " from " << printMBBReference(*MI->getParent())
- << " max delta=" << MaxDisp << " from " << getOffsetOf(MI)
- << " to " << DestOffset << " offset "
- << int(DestOffset - BrOffset) << "\t" << *MI);
- if (BrOffset <= DestOffset) {
- // Branch before the Dest.
- if (DestOffset-BrOffset <= MaxDisp)
- return true;
- } else {
- if (BrOffset-DestOffset <= MaxDisp)
- return true;
- }
- return false;
- }
- void ARMBasicBlockUtils::adjustBBOffsetsAfter(MachineBasicBlock *BB) {
- assert(BB->getParent() == &MF &&
- "Basic block is not a child of the current function.\n");
- unsigned BBNum = BB->getNumber();
- LLVM_DEBUG(dbgs() << "Adjust block:\n"
- << " - name: " << BB->getName() << "\n"
- << " - number: " << BB->getNumber() << "\n"
- << " - function: " << MF.getName() << "\n"
- << " - blocks: " << MF.getNumBlockIDs() << "\n");
- for(unsigned i = BBNum + 1, e = MF.getNumBlockIDs(); i < e; ++i) {
- // Get the offset and known bits at the end of the layout predecessor.
- // Include the alignment of the current block.
- const Align Align = MF.getBlockNumbered(i)->getAlignment();
- const unsigned Offset = BBInfo[i - 1].postOffset(Align);
- const unsigned KnownBits = BBInfo[i - 1].postKnownBits(Align);
- // This is where block i begins. Stop if the offset is already correct,
- // and we have updated 2 blocks. This is the maximum number of blocks
- // changed before calling this function.
- if (i > BBNum + 2 &&
- BBInfo[i].Offset == Offset &&
- BBInfo[i].KnownBits == KnownBits)
- break;
- BBInfo[i].Offset = Offset;
- BBInfo[i].KnownBits = KnownBits;
- }
- }
- } // end namespace llvm
|