mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
[ARM] Add ARMBasicBlockInfo.cpp
Forgot to add file! llvm-svn: 363531
This commit is contained in:
parent
7806cead69
commit
0db1b676fa
146
lib/Target/ARM/ARMBasicBlockInfo.cpp
Normal file
146
lib/Target/ARM/ARMBasicBlockInfo.cpp
Normal file
@ -0,0 +1,146 @@
|
||||
//===--- 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()->ensureAlignment(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)->getAlignment();
|
||||
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
|
Loading…
Reference in New Issue
Block a user