ARMBasicBlockInfo.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. //===--- ARMBasicBlockInfo.cpp - Utilities for block sizes ---------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "ARMBasicBlockInfo.h"
  9. #include "ARM.h"
  10. #include "ARMBaseInstrInfo.h"
  11. #include "ARMMachineFunctionInfo.h"
  12. #include "llvm/CodeGen/MachineBasicBlock.h"
  13. #include "llvm/CodeGen/MachineFunction.h"
  14. #include "llvm/CodeGen/MachineInstr.h"
  15. #include "llvm/CodeGen/TargetSubtargetInfo.h"
  16. #include "llvm/IR/GlobalVariable.h"
  17. #include "llvm/Support/Debug.h"
  18. #include <vector>
  19. #define DEBUG_TYPE "arm-bb-utils"
  20. using namespace llvm;
  21. namespace llvm {
  22. // mayOptimizeThumb2Instruction - Returns true if optimizeThumb2Instructions
  23. // below may shrink MI.
  24. static bool
  25. mayOptimizeThumb2Instruction(const MachineInstr *MI) {
  26. switch(MI->getOpcode()) {
  27. // optimizeThumb2Instructions.
  28. case ARM::t2LEApcrel:
  29. case ARM::t2LDRpci:
  30. // optimizeThumb2Branches.
  31. case ARM::t2B:
  32. case ARM::t2Bcc:
  33. case ARM::tBcc:
  34. // optimizeThumb2JumpTables.
  35. case ARM::t2BR_JT:
  36. case ARM::tBR_JTr:
  37. return true;
  38. }
  39. return false;
  40. }
  41. void ARMBasicBlockUtils::computeBlockSize(MachineBasicBlock *MBB) {
  42. LLVM_DEBUG(dbgs() << "computeBlockSize: " << MBB->getName() << "\n");
  43. BasicBlockInfo &BBI = BBInfo[MBB->getNumber()];
  44. BBI.Size = 0;
  45. BBI.Unalign = 0;
  46. BBI.PostAlign = Align(1);
  47. for (MachineInstr &I : *MBB) {
  48. BBI.Size += TII->getInstSizeInBytes(I);
  49. // For inline asm, getInstSizeInBytes returns a conservative estimate.
  50. // The actual size may be smaller, but still a multiple of the instr size.
  51. if (I.isInlineAsm())
  52. BBI.Unalign = isThumb ? 1 : 2;
  53. // Also consider instructions that may be shrunk later.
  54. else if (isThumb && mayOptimizeThumb2Instruction(&I))
  55. BBI.Unalign = 1;
  56. }
  57. // tBR_JTr contains a .align 2 directive.
  58. if (!MBB->empty() && MBB->back().getOpcode() == ARM::tBR_JTr) {
  59. BBI.PostAlign = Align(4);
  60. MBB->getParent()->ensureAlignment(Align(4));
  61. }
  62. }
  63. /// getOffsetOf - Return the current offset of the specified machine instruction
  64. /// from the start of the function. This offset changes as stuff is moved
  65. /// around inside the function.
  66. unsigned ARMBasicBlockUtils::getOffsetOf(MachineInstr *MI) const {
  67. const MachineBasicBlock *MBB = MI->getParent();
  68. // The offset is composed of two things: the sum of the sizes of all MBB's
  69. // before this instruction's block, and the offset from the start of the block
  70. // it is in.
  71. unsigned Offset = BBInfo[MBB->getNumber()].Offset;
  72. // Sum instructions before MI in MBB.
  73. for (MachineBasicBlock::const_iterator I = MBB->begin(); &*I != MI; ++I) {
  74. assert(I != MBB->end() && "Didn't find MI in its own basic block?");
  75. Offset += TII->getInstSizeInBytes(*I);
  76. }
  77. return Offset;
  78. }
  79. /// isBBInRange - Returns true if the distance between specific MI and
  80. /// specific BB can fit in MI's displacement field.
  81. bool ARMBasicBlockUtils::isBBInRange(MachineInstr *MI,
  82. MachineBasicBlock *DestBB,
  83. unsigned MaxDisp) const {
  84. unsigned PCAdj = isThumb ? 4 : 8;
  85. unsigned BrOffset = getOffsetOf(MI) + PCAdj;
  86. unsigned DestOffset = BBInfo[DestBB->getNumber()].Offset;
  87. LLVM_DEBUG(dbgs() << "Branch of destination " << printMBBReference(*DestBB)
  88. << " from " << printMBBReference(*MI->getParent())
  89. << " max delta=" << MaxDisp << " from " << getOffsetOf(MI)
  90. << " to " << DestOffset << " offset "
  91. << int(DestOffset - BrOffset) << "\t" << *MI);
  92. if (BrOffset <= DestOffset) {
  93. // Branch before the Dest.
  94. if (DestOffset-BrOffset <= MaxDisp)
  95. return true;
  96. } else {
  97. if (BrOffset-DestOffset <= MaxDisp)
  98. return true;
  99. }
  100. return false;
  101. }
  102. void ARMBasicBlockUtils::adjustBBOffsetsAfter(MachineBasicBlock *BB) {
  103. assert(BB->getParent() == &MF &&
  104. "Basic block is not a child of the current function.\n");
  105. unsigned BBNum = BB->getNumber();
  106. LLVM_DEBUG(dbgs() << "Adjust block:\n"
  107. << " - name: " << BB->getName() << "\n"
  108. << " - number: " << BB->getNumber() << "\n"
  109. << " - function: " << MF.getName() << "\n"
  110. << " - blocks: " << MF.getNumBlockIDs() << "\n");
  111. for(unsigned i = BBNum + 1, e = MF.getNumBlockIDs(); i < e; ++i) {
  112. // Get the offset and known bits at the end of the layout predecessor.
  113. // Include the alignment of the current block.
  114. const Align Align = MF.getBlockNumbered(i)->getAlignment();
  115. const unsigned Offset = BBInfo[i - 1].postOffset(Align);
  116. const unsigned KnownBits = BBInfo[i - 1].postKnownBits(Align);
  117. // This is where block i begins. Stop if the offset is already correct,
  118. // and we have updated 2 blocks. This is the maximum number of blocks
  119. // changed before calling this function.
  120. if (i > BBNum + 2 &&
  121. BBInfo[i].Offset == Offset &&
  122. BBInfo[i].KnownBits == KnownBits)
  123. break;
  124. BBInfo[i].Offset = Offset;
  125. BBInfo[i].KnownBits = KnownBits;
  126. }
  127. }
  128. } // end namespace llvm