summaryrefslogtreecommitdiff
path: root/lib/Target/ARM/ARMConstantIslandPass.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/ARM/ARMConstantIslandPass.cpp')
-rw-r--r--lib/Target/ARM/ARMConstantIslandPass.cpp44
1 files changed, 29 insertions, 15 deletions
diff --git a/lib/Target/ARM/ARMConstantIslandPass.cpp b/lib/Target/ARM/ARMConstantIslandPass.cpp
index f81361fa7d..6fc46b29a7 100644
--- a/lib/Target/ARM/ARMConstantIslandPass.cpp
+++ b/lib/Target/ARM/ARMConstantIslandPass.cpp
@@ -270,6 +270,7 @@ namespace {
private:
void DoInitialPlacement(std::vector<MachineInstr*> &CPEMIs);
CPEntry *findConstPoolEntry(unsigned CPI, const MachineInstr *CPEMI);
+ unsigned getCPELogAlign(const MachineInstr *CPEMI);
void JumpTableFunctionScan();
void InitialFunctionScan(const std::vector<MachineInstr*> &CPEMIs);
MachineBasicBlock *SplitBlockBeforeInstr(MachineInstr *MI);
@@ -402,11 +403,8 @@ bool ARMConstantIslands::runOnMachineFunction(MachineFunction &mf) {
// Perform the initial placement of the constant pool entries. To start with,
// we put them all at the end of the function.
std::vector<MachineInstr*> CPEMIs;
- if (!MCP->isEmpty()) {
+ if (!MCP->isEmpty())
DoInitialPlacement(CPEMIs);
- if (isThumb1)
- MF->EnsureAlignment(2); // 2 = log2(4)
- }
/// The next UID to take is the first unused one.
AFI->initPICLabelUId(CPEMIs.size());
@@ -499,6 +497,10 @@ ARMConstantIslands::DoInitialPlacement(std::vector<MachineInstr*> &CPEMIs) {
// If AlignConstantIslands isn't set, use 4-byte alignment for everything.
BB->setAlignment(AlignConstantIslands ? MaxAlign : 2);
+ // The function needs to be as aligned as the basic blocks. The linker may
+ // move functions around based on their alignment.
+ MF->EnsureAlignment(BB->getAlignment());
+
// Order the entries in BB by descending alignment. That ensures correct
// alignment of all entries as long as BB is sufficiently aligned. Keep
// track of the insertion point for each alignment. We are going to bucket
@@ -577,6 +579,22 @@ ARMConstantIslands::CPEntry
return NULL;
}
+/// getCPELogAlign - Returns the required alignment of the constant pool entry
+/// represented by CPEMI. ALignment is measured in log2(bytes) units.
+unsigned ARMConstantIslands::getCPELogAlign(const MachineInstr *CPEMI) {
+ assert(CPEMI && CPEMI->getOpcode() == ARM::CONSTPOOL_ENTRY);
+
+ // Everything is 4-byte aligned unless AlignConstantIslands is set.
+ if (!AlignConstantIslands)
+ return 2;
+
+ unsigned CPI = CPEMI->getOperand(1).getIndex();
+ assert(CPI < MCP->getConstants().size() && "Invalid constant pool index.");
+ unsigned Align = MCP->getConstants()[CPI].getAlignment();
+ assert(isPowerOf2_32(Align) && "Invalid CPE alignment");
+ return Log2_32(Align);
+}
+
/// JumpTableFunctionScan - Do a scan of the function, building up
/// information about the sizes of each block and the locations of all
/// the jump tables.
@@ -1367,8 +1385,8 @@ bool ARMConstantIslands::HandleConstantPoolUser(unsigned CPUserIndex) {
CPEntries[CPI].push_back(CPEntry(U.CPEMI, ID, 1));
++NumCPEs;
- // Mark the basic block as 4-byte aligned as required by the const-pool entry.
- NewIsland->setAlignment(2);
+ // Mark the basic block as aligned as required by the const-pool entry.
+ NewIsland->setAlignment(getCPELogAlign(U.CPEMI));
// Increase the size of the island block to account for the new entry.
BBInfo[NewIsland->getNumber()].Size += Size;
@@ -1396,18 +1414,14 @@ void ARMConstantIslands::RemoveDeadCPEMI(MachineInstr *CPEMI) {
BBInfo[CPEBB->getNumber()].Size -= Size;
// All succeeding offsets have the current size value added in, fix this.
if (CPEBB->empty()) {
- // In thumb1 mode, the size of island may be padded by two to compensate for
- // the alignment requirement. Then it will now be 2 when the block is
- // empty, so fix this.
- // All succeeding offsets have the current size value added in, fix this.
- if (BBInfo[CPEBB->getNumber()].Size != 0) {
- Size += BBInfo[CPEBB->getNumber()].Size;
- BBInfo[CPEBB->getNumber()].Size = 0;
- }
+ BBInfo[CPEBB->getNumber()].Size = 0;
// This block no longer needs to be aligned. <rdar://problem/10534709>.
CPEBB->setAlignment(0);
- }
+ } else
+ // Entries are sorted by descending alignment, so realign from the front.
+ CPEBB->setAlignment(getCPELogAlign(CPEBB->begin()));
+
AdjustBBOffsetsAfter(CPEBB);
// An island has only one predecessor BB and one successor BB. Check if
// this BB's predecessor jumps directly to this BB's successor. This