//===-- ARMConstantIslandPass.cpp - ARM constant islands --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains a pass that splits the constant pool up into 'islands'
// which are scattered through-out the function. This is required due to the
// limited pc-relative displacements that ARM has.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "arm-cp-islands"
#include "ARM.h"
#include "ARMMachineFunctionInfo.h"
#include "ARMInstrInfo.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Statistic.h"
using namespace llvm;
STATISTIC(NumCPEs, "Number of constpool entries");
STATISTIC(NumSplit, "Number of uncond branches inserted");
STATISTIC(NumCBrFixed, "Number of cond branches fixed");
STATISTIC(NumUBrFixed, "Number of uncond branches fixed");
namespace {
/// ARMConstantIslands - Due to limited PC-relative displacements, ARM
/// requires constant pool entries to be scattered among the instructions
/// inside a function. To do this, it completely ignores the normal LLVM
/// constant pool; instead, it places constants wherever it feels like with
/// special instructions.
///
/// The terminology used in this pass includes:
/// Islands - Clumps of constants placed in the function.
/// Water - Potential places where an island could be formed.
/// CPE - A constant pool entry that has been placed somewhere, which
/// tracks a list of users.
class VISIBILITY_HIDDEN ARMConstantIslands : public MachineFunctionPass {
/// NextUID - Assign unique ID's to CPE's.
unsigned NextUID;
/// BBSizes - The size of each MachineBasicBlock in bytes of code, indexed
/// by MBB Number. The two-byte pads required for Thumb alignment are
/// counted as part of the following block (i.e., the offset and size for
/// a padded block will both be ==2 mod 4).
std::vector<unsigned> BBSizes;
/// BBOffsets - the offset of each MBB in bytes, starting from 0.
/// The two-byte pads required for Thumb alignment are counted as part of
/// the following block.
std::vector<unsigned> BBOffsets;
/// WaterList - A sorted list of basic blocks where islands could be placed
/// (i.e. blocks that don't fall through to the following block, due
/// to a return, unreachable, or unconditional branch).
std::vector<MachineBasicBlock*> WaterList;
/// CPUser - One user of a constant pool, keeping the machine instruction
/// pointer, the constant pool being referenced, and the max displacement
/// allowed from the instruction to the CP.
struct CPUser {
MachineInstr *MI;
MachineInstr *CPEMI;
unsigned MaxDisp;
CPUser(MachineInstr *mi, MachineInstr *cpemi, unsigned maxdisp)
: MI(mi), CPEMI(cpemi), MaxDisp(maxdisp) {}
};
/// CPUsers - Keep track of all of the machine instructions that use various
/// constant pools and their max displacement.
std::vector<CPUser> CPUsers;
/// CPEntry - One per constant pool entry, keeping the machine instruction
/// pointer, the constpool index, and the number of CPUser's which
/// reference this entry.
struct CPEntry {
MachineInstr *CPEMI;
unsigned CPI;
unsigned RefCount;
CPEntry(MachineInstr *cpemi, unsigned cp