Home | History | Annotate | Download | only in ARM
      1 //===-- ARMConstantPoolValue.cpp - ARM constantpool value -----------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file implements the ARM specific constantpool value class.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "ARMConstantPoolValue.h"
     15 #include "llvm/ADT/FoldingSet.h"
     16 #include "llvm/CodeGen/MachineBasicBlock.h"
     17 #include "llvm/IR/Constant.h"
     18 #include "llvm/IR/Constants.h"
     19 #include "llvm/IR/GlobalValue.h"
     20 #include "llvm/IR/Type.h"
     21 #include "llvm/Support/raw_ostream.h"
     22 #include <cstdlib>
     23 using namespace llvm;
     24 
     25 //===----------------------------------------------------------------------===//
     26 // ARMConstantPoolValue
     27 //===----------------------------------------------------------------------===//
     28 
     29 ARMConstantPoolValue::ARMConstantPoolValue(Type *Ty, unsigned id,
     30                                            ARMCP::ARMCPKind kind,
     31                                            unsigned char PCAdj,
     32                                            ARMCP::ARMCPModifier modifier,
     33                                            bool addCurrentAddress)
     34   : MachineConstantPoolValue(Ty), LabelId(id), Kind(kind),
     35     PCAdjust(PCAdj), Modifier(modifier),
     36     AddCurrentAddress(addCurrentAddress) {}
     37 
     38 ARMConstantPoolValue::ARMConstantPoolValue(LLVMContext &C, unsigned id,
     39                                            ARMCP::ARMCPKind kind,
     40                                            unsigned char PCAdj,
     41                                            ARMCP::ARMCPModifier modifier,
     42                                            bool addCurrentAddress)
     43   : MachineConstantPoolValue((Type*)Type::getInt32Ty(C)),
     44     LabelId(id), Kind(kind), PCAdjust(PCAdj), Modifier(modifier),
     45     AddCurrentAddress(addCurrentAddress) {}
     46 
     47 ARMConstantPoolValue::~ARMConstantPoolValue() {}
     48 
     49 const char *ARMConstantPoolValue::getModifierText() const {
     50   switch (Modifier) {
     51     // FIXME: Are these case sensitive? It'd be nice to lower-case all the
     52     // strings if that's legal.
     53   case ARMCP::no_modifier:
     54     return "none";
     55   case ARMCP::TLSGD:
     56     return "tlsgd";
     57   case ARMCP::GOT_PREL:
     58     return "GOT_PREL";
     59   case ARMCP::GOTTPOFF:
     60     return "gottpoff";
     61   case ARMCP::TPOFF:
     62     return "tpoff";
     63   case ARMCP::SECREL:
     64     return "secrel32";
     65   }
     66   llvm_unreachable("Unknown modifier!");
     67 }
     68 
     69 int ARMConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP,
     70                                                     unsigned Alignment) {
     71   llvm_unreachable("Shouldn't be calling this directly!");
     72 }
     73 
     74 void
     75 ARMConstantPoolValue::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
     76   ID.AddInteger(LabelId);
     77   ID.AddInteger(PCAdjust);
     78 }
     79 
     80 bool
     81 ARMConstantPoolValue::hasSameValue(ARMConstantPoolValue *ACPV) {
     82   if (ACPV->Kind == Kind &&
     83       ACPV->PCAdjust == PCAdjust &&
     84       ACPV->Modifier == Modifier &&
     85       ACPV->LabelId == LabelId &&
     86       ACPV->AddCurrentAddress == AddCurrentAddress) {
     87     // Two PC relative constpool entries containing the same GV address or
     88     // external symbols. FIXME: What about blockaddress?
     89     if (Kind == ARMCP::CPValue || Kind == ARMCP::CPExtSymbol)
     90       return true;
     91   }
     92   return false;
     93 }
     94 
     95 LLVM_DUMP_METHOD void ARMConstantPoolValue::dump() const {
     96   errs() << "  " << *this;
     97 }
     98 
     99 void ARMConstantPoolValue::print(raw_ostream &O) const {
    100   if (Modifier) O << "(" << getModifierText() << ")";
    101   if (PCAdjust != 0) {
    102     O << "-(LPC" << LabelId << "+" << (unsigned)PCAdjust;
    103     if (AddCurrentAddress) O << "-.";
    104     O << ")";
    105   }
    106 }
    107 
    108 //===----------------------------------------------------------------------===//
    109 // ARMConstantPoolConstant
    110 //===----------------------------------------------------------------------===//
    111 
    112 ARMConstantPoolConstant::ARMConstantPoolConstant(Type *Ty,
    113                                                  const Constant *C,
    114                                                  unsigned ID,
    115                                                  ARMCP::ARMCPKind Kind,
    116                                                  unsigned char PCAdj,
    117                                                  ARMCP::ARMCPModifier Modifier,
    118                                                  bool AddCurrentAddress)
    119   : ARMConstantPoolValue(Ty, ID, Kind, PCAdj, Modifier, AddCurrentAddress),
    120     CVal(C) {}
    121 
    122 ARMConstantPoolConstant::ARMConstantPoolConstant(const Constant *C,
    123                                                  unsigned ID,
    124                                                  ARMCP::ARMCPKind Kind,
    125                                                  unsigned char PCAdj,
    126                                                  ARMCP::ARMCPModifier Modifier,
    127                                                  bool AddCurrentAddress)
    128   : ARMConstantPoolValue((Type*)C->getType(), ID, Kind, PCAdj, Modifier,
    129                          AddCurrentAddress),
    130     CVal(C) {}
    131 
    132 ARMConstantPoolConstant *
    133 ARMConstantPoolConstant::Create(const Constant *C, unsigned ID) {
    134   return new ARMConstantPoolConstant(C, ID, ARMCP::CPValue, 0,
    135                                      ARMCP::no_modifier, false);
    136 }
    137 
    138 ARMConstantPoolConstant *
    139 ARMConstantPoolConstant::Create(const GlobalValue *GV,
    140                                 ARMCP::ARMCPModifier Modifier) {
    141   return new ARMConstantPoolConstant((Type*)Type::getInt32Ty(GV->getContext()),
    142                                      GV, 0, ARMCP::CPValue, 0,
    143                                      Modifier, false);
    144 }
    145 
    146 ARMConstantPoolConstant *
    147 ARMConstantPoolConstant::Create(const Constant *C, unsigned ID,
    148                                 ARMCP::ARMCPKind Kind, unsigned char PCAdj) {
    149   return new ARMConstantPoolConstant(C, ID, Kind, PCAdj,
    150                                      ARMCP::no_modifier, false);
    151 }
    152 
    153 ARMConstantPoolConstant *
    154 ARMConstantPoolConstant::Create(const Constant *C, unsigned ID,
    155                                 ARMCP::ARMCPKind Kind, unsigned char PCAdj,
    156                                 ARMCP::ARMCPModifier Modifier,
    157                                 bool AddCurrentAddress) {
    158   return new ARMConstantPoolConstant(C, ID, Kind, PCAdj, Modifier,
    159                                      AddCurrentAddress);
    160 }
    161 
    162 const GlobalValue *ARMConstantPoolConstant::getGV() const {
    163   return dyn_cast_or_null<GlobalValue>(CVal);
    164 }
    165 
    166 const BlockAddress *ARMConstantPoolConstant::getBlockAddress() const {
    167   return dyn_cast_or_null<BlockAddress>(CVal);
    168 }
    169 
    170 int ARMConstantPoolConstant::getExistingMachineCPValue(MachineConstantPool *CP,
    171                                                        unsigned Alignment) {
    172   return getExistingMachineCPValueImpl<ARMConstantPoolConstant>(CP, Alignment);
    173 }
    174 
    175 bool ARMConstantPoolConstant::hasSameValue(ARMConstantPoolValue *ACPV) {
    176   const ARMConstantPoolConstant *ACPC = dyn_cast<ARMConstantPoolConstant>(ACPV);
    177   return ACPC && ACPC->CVal == CVal && ARMConstantPoolValue::hasSameValue(ACPV);
    178 }
    179 
    180 void ARMConstantPoolConstant::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
    181   ID.AddPointer(CVal);
    182   ARMConstantPoolValue::addSelectionDAGCSEId(ID);
    183 }
    184 
    185 void ARMConstantPoolConstant::print(raw_ostream &O) const {
    186   O << CVal->getName();
    187   ARMConstantPoolValue::print(O);
    188 }
    189 
    190 //===----------------------------------------------------------------------===//
    191 // ARMConstantPoolSymbol
    192 //===----------------------------------------------------------------------===//
    193 
    194 ARMConstantPoolSymbol::ARMConstantPoolSymbol(LLVMContext &C, const char *s,
    195                                              unsigned id,
    196                                              unsigned char PCAdj,
    197                                              ARMCP::ARMCPModifier Modifier,
    198                                              bool AddCurrentAddress)
    199   : ARMConstantPoolValue(C, id, ARMCP::CPExtSymbol, PCAdj, Modifier,
    200                          AddCurrentAddress),
    201     S(s) {}
    202 
    203 ARMConstantPoolSymbol *
    204 ARMConstantPoolSymbol::Create(LLVMContext &C, const char *s,
    205                               unsigned ID, unsigned char PCAdj) {
    206   return new ARMConstantPoolSymbol(C, s, ID, PCAdj, ARMCP::no_modifier, false);
    207 }
    208 
    209 int ARMConstantPoolSymbol::getExistingMachineCPValue(MachineConstantPool *CP,
    210                                                      unsigned Alignment) {
    211   return getExistingMachineCPValueImpl<ARMConstantPoolSymbol>(CP, Alignment);
    212 }
    213 
    214 bool ARMConstantPoolSymbol::hasSameValue(ARMConstantPoolValue *ACPV) {
    215   const ARMConstantPoolSymbol *ACPS = dyn_cast<ARMConstantPoolSymbol>(ACPV);
    216   return ACPS && ACPS->S == S && ARMConstantPoolValue::hasSameValue(ACPV);
    217 }
    218 
    219 void ARMConstantPoolSymbol::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
    220   ID.AddString(S);
    221   ARMConstantPoolValue::addSelectionDAGCSEId(ID);
    222 }
    223 
    224 void ARMConstantPoolSymbol::print(raw_ostream &O) const {
    225   O << S;
    226   ARMConstantPoolValue::print(O);
    227 }
    228 
    229 //===----------------------------------------------------------------------===//
    230 // ARMConstantPoolMBB
    231 //===----------------------------------------------------------------------===//
    232 
    233 ARMConstantPoolMBB::ARMConstantPoolMBB(LLVMContext &C,
    234                                        const MachineBasicBlock *mbb,
    235                                        unsigned id, unsigned char PCAdj,
    236                                        ARMCP::ARMCPModifier Modifier,
    237                                        bool AddCurrentAddress)
    238   : ARMConstantPoolValue(C, id, ARMCP::CPMachineBasicBlock, PCAdj,
    239                          Modifier, AddCurrentAddress),
    240     MBB(mbb) {}
    241 
    242 ARMConstantPoolMBB *ARMConstantPoolMBB::Create(LLVMContext &C,
    243                                                const MachineBasicBlock *mbb,
    244                                                unsigned ID,
    245                                                unsigned char PCAdj) {
    246   return new ARMConstantPoolMBB(C, mbb, ID, PCAdj, ARMCP::no_modifier, false);
    247 }
    248 
    249 int ARMConstantPoolMBB::getExistingMachineCPValue(MachineConstantPool *CP,
    250                                                   unsigned Alignment) {
    251   return getExistingMachineCPValueImpl<ARMConstantPoolMBB>(CP, Alignment);
    252 }
    253 
    254 bool ARMConstantPoolMBB::hasSameValue(ARMConstantPoolValue *ACPV) {
    255   const ARMConstantPoolMBB *ACPMBB = dyn_cast<ARMConstantPoolMBB>(ACPV);
    256   return ACPMBB && ACPMBB->MBB == MBB &&
    257     ARMConstantPoolValue::hasSameValue(ACPV);
    258 }
    259 
    260 void ARMConstantPoolMBB::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
    261   ID.AddPointer(MBB);
    262   ARMConstantPoolValue::addSelectionDAGCSEId(ID);
    263 }
    264 
    265 void ARMConstantPoolMBB::print(raw_ostream &O) const {
    266   O << "BB#" << MBB->getNumber();
    267   ARMConstantPoolValue::print(O);
    268 }
    269