mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
b5914c76cc
In PIC mode we were previously computing global variable addresses (or GOT entry addresses) by adding the PC, the PC-relative GOT displacement and the GOT-relative symbol/GOT entry displacement. Because the latter two displacements are fixed, we ended up performing one more addition than necessary. This change causes us to compute addresses using a single PC-relative displacement, resulting in a shorter code sequence. This reduces code size by about 4% in a recent build of Chromium for Android. As a result of this change we no longer need to compute the GOT base address in the ARM backend, which allows us to remove the Global Base Reg pass and SDAG lowering for the GOT. We also now no longer use the GOT when addressing a symbol which is known to be defined in the same linkage unit. Specifically, the symbol must have either hidden visibility or a strong definition in the current module in order to not use the the GOT. This is a change from the previous behaviour where we would use the GOT to address externally visible symbols defined in the same module. I think the only cases where this could matter are cases involving symbol interposition, but we don't really support that well anyway. Differential Revision: http://reviews.llvm.org/D13650 llvm-svn: 251322
262 lines
10 KiB
C++
262 lines
10 KiB
C++
//===-- ARMConstantPoolValue.cpp - ARM constantpool value -----------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file implements the ARM specific constantpool value class.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "ARMConstantPoolValue.h"
|
|
#include "llvm/ADT/FoldingSet.h"
|
|
#include "llvm/CodeGen/MachineBasicBlock.h"
|
|
#include "llvm/IR/Constant.h"
|
|
#include "llvm/IR/Constants.h"
|
|
#include "llvm/IR/GlobalValue.h"
|
|
#include "llvm/IR/Type.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
#include <cstdlib>
|
|
using namespace llvm;
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// ARMConstantPoolValue
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
ARMConstantPoolValue::ARMConstantPoolValue(Type *Ty, unsigned id,
|
|
ARMCP::ARMCPKind kind,
|
|
unsigned char PCAdj,
|
|
ARMCP::ARMCPModifier modifier,
|
|
bool addCurrentAddress)
|
|
: MachineConstantPoolValue(Ty), LabelId(id), Kind(kind),
|
|
PCAdjust(PCAdj), Modifier(modifier),
|
|
AddCurrentAddress(addCurrentAddress) {}
|
|
|
|
ARMConstantPoolValue::ARMConstantPoolValue(LLVMContext &C, unsigned id,
|
|
ARMCP::ARMCPKind kind,
|
|
unsigned char PCAdj,
|
|
ARMCP::ARMCPModifier modifier,
|
|
bool addCurrentAddress)
|
|
: MachineConstantPoolValue((Type*)Type::getInt32Ty(C)),
|
|
LabelId(id), Kind(kind), PCAdjust(PCAdj), Modifier(modifier),
|
|
AddCurrentAddress(addCurrentAddress) {}
|
|
|
|
ARMConstantPoolValue::~ARMConstantPoolValue() {}
|
|
|
|
const char *ARMConstantPoolValue::getModifierText() const {
|
|
switch (Modifier) {
|
|
// FIXME: Are these case sensitive? It'd be nice to lower-case all the
|
|
// strings if that's legal.
|
|
case ARMCP::no_modifier: return "none";
|
|
case ARMCP::TLSGD: return "tlsgd";
|
|
case ARMCP::GOT_PREL: return "GOT_PREL";
|
|
case ARMCP::GOTTPOFF: return "gottpoff";
|
|
case ARMCP::TPOFF: return "tpoff";
|
|
}
|
|
llvm_unreachable("Unknown modifier!");
|
|
}
|
|
|
|
int ARMConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP,
|
|
unsigned Alignment) {
|
|
llvm_unreachable("Shouldn't be calling this directly!");
|
|
}
|
|
|
|
void
|
|
ARMConstantPoolValue::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
|
|
ID.AddInteger(LabelId);
|
|
ID.AddInteger(PCAdjust);
|
|
}
|
|
|
|
bool
|
|
ARMConstantPoolValue::hasSameValue(ARMConstantPoolValue *ACPV) {
|
|
if (ACPV->Kind == Kind &&
|
|
ACPV->PCAdjust == PCAdjust &&
|
|
ACPV->Modifier == Modifier) {
|
|
if (ACPV->LabelId == LabelId)
|
|
return true;
|
|
// Two PC relative constpool entries containing the same GV address or
|
|
// external symbols. FIXME: What about blockaddress?
|
|
if (Kind == ARMCP::CPValue || Kind == ARMCP::CPExtSymbol)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void ARMConstantPoolValue::dump() const {
|
|
errs() << " " << *this;
|
|
}
|
|
|
|
void ARMConstantPoolValue::print(raw_ostream &O) const {
|
|
if (Modifier) O << "(" << getModifierText() << ")";
|
|
if (PCAdjust != 0) {
|
|
O << "-(LPC" << LabelId << "+" << (unsigned)PCAdjust;
|
|
if (AddCurrentAddress) O << "-.";
|
|
O << ")";
|
|
}
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// ARMConstantPoolConstant
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
ARMConstantPoolConstant::ARMConstantPoolConstant(Type *Ty,
|
|
const Constant *C,
|
|
unsigned ID,
|
|
ARMCP::ARMCPKind Kind,
|
|
unsigned char PCAdj,
|
|
ARMCP::ARMCPModifier Modifier,
|
|
bool AddCurrentAddress)
|
|
: ARMConstantPoolValue(Ty, ID, Kind, PCAdj, Modifier, AddCurrentAddress),
|
|
CVal(C) {}
|
|
|
|
ARMConstantPoolConstant::ARMConstantPoolConstant(const Constant *C,
|
|
unsigned ID,
|
|
ARMCP::ARMCPKind Kind,
|
|
unsigned char PCAdj,
|
|
ARMCP::ARMCPModifier Modifier,
|
|
bool AddCurrentAddress)
|
|
: ARMConstantPoolValue((Type*)C->getType(), ID, Kind, PCAdj, Modifier,
|
|
AddCurrentAddress),
|
|
CVal(C) {}
|
|
|
|
ARMConstantPoolConstant *
|
|
ARMConstantPoolConstant::Create(const Constant *C, unsigned ID) {
|
|
return new ARMConstantPoolConstant(C, ID, ARMCP::CPValue, 0,
|
|
ARMCP::no_modifier, false);
|
|
}
|
|
|
|
ARMConstantPoolConstant *
|
|
ARMConstantPoolConstant::Create(const GlobalValue *GV,
|
|
ARMCP::ARMCPModifier Modifier) {
|
|
return new ARMConstantPoolConstant((Type*)Type::getInt32Ty(GV->getContext()),
|
|
GV, 0, ARMCP::CPValue, 0,
|
|
Modifier, false);
|
|
}
|
|
|
|
ARMConstantPoolConstant *
|
|
ARMConstantPoolConstant::Create(const Constant *C, unsigned ID,
|
|
ARMCP::ARMCPKind Kind, unsigned char PCAdj) {
|
|
return new ARMConstantPoolConstant(C, ID, Kind, PCAdj,
|
|
ARMCP::no_modifier, false);
|
|
}
|
|
|
|
ARMConstantPoolConstant *
|
|
ARMConstantPoolConstant::Create(const Constant *C, unsigned ID,
|
|
ARMCP::ARMCPKind Kind, unsigned char PCAdj,
|
|
ARMCP::ARMCPModifier Modifier,
|
|
bool AddCurrentAddress) {
|
|
return new ARMConstantPoolConstant(C, ID, Kind, PCAdj, Modifier,
|
|
AddCurrentAddress);
|
|
}
|
|
|
|
const GlobalValue *ARMConstantPoolConstant::getGV() const {
|
|
return dyn_cast_or_null<GlobalValue>(CVal);
|
|
}
|
|
|
|
const BlockAddress *ARMConstantPoolConstant::getBlockAddress() const {
|
|
return dyn_cast_or_null<BlockAddress>(CVal);
|
|
}
|
|
|
|
int ARMConstantPoolConstant::getExistingMachineCPValue(MachineConstantPool *CP,
|
|
unsigned Alignment) {
|
|
return getExistingMachineCPValueImpl<ARMConstantPoolConstant>(CP, Alignment);
|
|
}
|
|
|
|
bool ARMConstantPoolConstant::hasSameValue(ARMConstantPoolValue *ACPV) {
|
|
const ARMConstantPoolConstant *ACPC = dyn_cast<ARMConstantPoolConstant>(ACPV);
|
|
return ACPC && ACPC->CVal == CVal && ARMConstantPoolValue::hasSameValue(ACPV);
|
|
}
|
|
|
|
void ARMConstantPoolConstant::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
|
|
ID.AddPointer(CVal);
|
|
ARMConstantPoolValue::addSelectionDAGCSEId(ID);
|
|
}
|
|
|
|
void ARMConstantPoolConstant::print(raw_ostream &O) const {
|
|
O << CVal->getName();
|
|
ARMConstantPoolValue::print(O);
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// ARMConstantPoolSymbol
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
ARMConstantPoolSymbol::ARMConstantPoolSymbol(LLVMContext &C, const char *s,
|
|
unsigned id,
|
|
unsigned char PCAdj,
|
|
ARMCP::ARMCPModifier Modifier,
|
|
bool AddCurrentAddress)
|
|
: ARMConstantPoolValue(C, id, ARMCP::CPExtSymbol, PCAdj, Modifier,
|
|
AddCurrentAddress),
|
|
S(s) {}
|
|
|
|
ARMConstantPoolSymbol *
|
|
ARMConstantPoolSymbol::Create(LLVMContext &C, const char *s,
|
|
unsigned ID, unsigned char PCAdj) {
|
|
return new ARMConstantPoolSymbol(C, s, ID, PCAdj, ARMCP::no_modifier, false);
|
|
}
|
|
|
|
int ARMConstantPoolSymbol::getExistingMachineCPValue(MachineConstantPool *CP,
|
|
unsigned Alignment) {
|
|
return getExistingMachineCPValueImpl<ARMConstantPoolSymbol>(CP, Alignment);
|
|
}
|
|
|
|
bool ARMConstantPoolSymbol::hasSameValue(ARMConstantPoolValue *ACPV) {
|
|
const ARMConstantPoolSymbol *ACPS = dyn_cast<ARMConstantPoolSymbol>(ACPV);
|
|
return ACPS && ACPS->S == S && ARMConstantPoolValue::hasSameValue(ACPV);
|
|
}
|
|
|
|
void ARMConstantPoolSymbol::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
|
|
ID.AddString(S);
|
|
ARMConstantPoolValue::addSelectionDAGCSEId(ID);
|
|
}
|
|
|
|
void ARMConstantPoolSymbol::print(raw_ostream &O) const {
|
|
O << S;
|
|
ARMConstantPoolValue::print(O);
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// ARMConstantPoolMBB
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
ARMConstantPoolMBB::ARMConstantPoolMBB(LLVMContext &C,
|
|
const MachineBasicBlock *mbb,
|
|
unsigned id, unsigned char PCAdj,
|
|
ARMCP::ARMCPModifier Modifier,
|
|
bool AddCurrentAddress)
|
|
: ARMConstantPoolValue(C, id, ARMCP::CPMachineBasicBlock, PCAdj,
|
|
Modifier, AddCurrentAddress),
|
|
MBB(mbb) {}
|
|
|
|
ARMConstantPoolMBB *ARMConstantPoolMBB::Create(LLVMContext &C,
|
|
const MachineBasicBlock *mbb,
|
|
unsigned ID,
|
|
unsigned char PCAdj) {
|
|
return new ARMConstantPoolMBB(C, mbb, ID, PCAdj, ARMCP::no_modifier, false);
|
|
}
|
|
|
|
int ARMConstantPoolMBB::getExistingMachineCPValue(MachineConstantPool *CP,
|
|
unsigned Alignment) {
|
|
return getExistingMachineCPValueImpl<ARMConstantPoolMBB>(CP, Alignment);
|
|
}
|
|
|
|
bool ARMConstantPoolMBB::hasSameValue(ARMConstantPoolValue *ACPV) {
|
|
const ARMConstantPoolMBB *ACPMBB = dyn_cast<ARMConstantPoolMBB>(ACPV);
|
|
return ACPMBB && ACPMBB->MBB == MBB &&
|
|
ARMConstantPoolValue::hasSameValue(ACPV);
|
|
}
|
|
|
|
void ARMConstantPoolMBB::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
|
|
ID.AddPointer(MBB);
|
|
ARMConstantPoolValue::addSelectionDAGCSEId(ID);
|
|
}
|
|
|
|
void ARMConstantPoolMBB::print(raw_ostream &O) const {
|
|
O << "BB#" << MBB->getNumber();
|
|
ARMConstantPoolValue::print(O);
|
|
}
|