mirror of
https://github.com/RPCS3/llvm.git
synced 2026-01-31 01:25:19 +01:00
Summary: This patch renames functions that takes or returns alignment as log2, this patch will help with the transition to llvm::Align. The renaming makes it explicit that we deal with log(alignment) instead of a power of two alignment. A few renames uncovered dubious assignments: - `MirParser`/`MirPrinter` was expecting powers of two but `MachineFunction` and `MachineBasicBlock` were using deal with log2(align). This patch fixes it and updates the documentation. - `MachineBlockPlacement` exposes two flags (`align-all-blocks` and `align-all-nofallthru-blocks`) supposedly interpreted as power of two alignments, internally these values are interpreted as log2(align). This patch updates the documentation, - `MachineFunctionexposes` exposes `align-all-functions` also interpreted as power of two alignment, internally this value is interpreted as log2(align). This patch updates the documentation, Reviewers: lattner, thegameg, courbet Subscribers: dschuff, arsenm, jyknight, dylanmckay, sdardis, nemanjai, jvesely, nhaehnle, javed.absar, hiraditya, kbarton, fedor.sergeev, asb, rbar, johnrusso, simoncook, apazos, sabuasal, niosHD, jrtc27, MaskRay, zzheng, edward-jones, atanasyan, rogfer01, MartinMosbeck, brucehoult, the_o, dexonsmith, PkmX, jocewei, jsji, Jim, s.egerton, llvm-commits, courbet Tags: #llvm Differential Revision: https://reviews.llvm.org/D65945 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@371045 91177308-0d34-0410-b5e6-96231b3b80d8
147 lines
5.1 KiB
C++
147 lines
5.1 KiB
C++
//===--- 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 "ARM.h"
|
|
#include "ARMBaseInstrInfo.h"
|
|
#include "ARMBasicBlockInfo.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 <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 = 0;
|
|
|
|
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 = 2;
|
|
MBB->getParent()->ensureLogAlignment(2);
|
|
}
|
|
}
|
|
|
|
/// 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.
|
|
unsigned LogAlign = MF.getBlockNumbered(i)->getLogAlignment();
|
|
unsigned Offset = BBInfo[i - 1].postOffset(LogAlign);
|
|
unsigned KnownBits = BBInfo[i - 1].postKnownBits(LogAlign);
|
|
|
|
// 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
|