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: return "none";
     54   case ARMCP::TLSGD:       return "tlsgd";
     55   case ARMCP::GOT:         return "GOT";
     56   case ARMCP::GOTOFF:      return "GOTOFF";
     57   case ARMCP::GOTTPOFF:    return "gottpoff";
     58   case ARMCP::TPOFF:       return "tpoff";
     59   }
     60   llvm_unreachable("Unknown modifier!");
     61 }
     62 
     63 int ARMConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP,
     64                                                     unsigned Alignment) {
     65   llvm_unreachable("Shouldn't be calling this directly!");
     66 }
     67 
     68 void
     69 ARMConstantPoolValue::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
     70   ID.AddInteger(LabelId);
     71   ID.AddInteger(PCAdjust);
     72 }
     73 
     74 bool
     75 ARMConstantPoolValue::hasSameValue(ARMConstantPoolValue *ACPV) {
     76   if (ACPV->Kind == Kind &&
     77       ACPV->PCAdjust == PCAdjust &&
     78       ACPV->Modifier == Modifier) {
     79     if (ACPV->LabelId == LabelId)
     80       return true;
     81     // Two PC relative constpool entries containing the same GV address or
     82     // external symbols. FIXME: What about blockaddress?
     83     if (Kind == ARMCP::CPValue || Kind == ARMCP::CPExtSymbol)
     84       return true;
     85   }
     86   return false;
     87 }
     88 
     89 void ARMConstantPoolValue::dump() const {
     90   errs() << "  " << *this;
     91 }
     92 
     93 void ARMConstantPoolValue::print(raw_ostream &O) const {
     94   if (Modifier) O << "(" << getModifierText() << ")";
     95   if (PCAdjust != 0) {
     96     O << "-(LPC" << LabelId << "+" << (unsigned)PCAdjust;
     97     if (AddCurrentAddress) O << "-.";
     98     O << ")";
     99   }
    100 }
    101 
    102 //===----------------------------------------------------------------------===//
    103 // ARMConstantPoolConstant
    104 //===----------------------------------------------------------------------===//
    105 
    106 ARMConstantPoolConstant::ARMConstantPoolConstant(Type *Ty,
    107                                                  const Constant *C,
    108                                                  unsigned ID,
    109                                                  ARMCP::ARMCPKind Kind,
    110                                                  unsigned char PCAdj,
    111                                                  ARMCP::ARMCPModifier Modifier,
    112                                                  bool AddCurrentAddress)
    113   : ARMConstantPoolValue(Ty, ID, Kind, PCAdj, Modifier, AddCurrentAddress),
    114     CVal(C) {}
    115 
    116 ARMConstantPoolConstant::ARMConstantPoolConstant(const Constant *C,
    117                                                  unsigned ID,
    118                                                  ARMCP::ARMCPKind Kind,
    119                                                  unsigned char PCAdj,
    120                                                  ARMCP::ARMCPModifier Modifier,
    121                                                  bool AddCurrentAddress)
    122   : ARMConstantPoolValue((Type*)C->getType(), ID, Kind, PCAdj, Modifier,
    123                          AddCurrentAddress),
    124     CVal(C) {}
    125 
    126 ARMConstantPoolConstant *
    127 ARMConstantPoolConstant::Create(const Constant *C, unsigned ID) {
    128   return new ARMConstantPoolConstant(C, ID, ARMCP::CPValue, 0,
    129                                      ARMCP::no_modifier, false);
    130 }
    131 
    132 ARMConstantPoolConstant *
    133 ARMConstantPoolConstant::Create(const GlobalValue *GV,
    134                                 ARMCP::ARMCPModifier Modifier) {
    135   return new ARMConstantPoolConstant((Type*)Type::getInt32Ty(GV->getContext()),
    136                                      GV, 0, ARMCP::CPValue, 0,
    137                                      Modifier, false);
    138 }
    139 
    140 ARMConstantPoolConstant *
    141 ARMConstantPoolConstant::Create(const Constant *C, unsigned ID,
    142                                 ARMCP::ARMCPKind Kind, unsigned char PCAdj) {
    143   return new ARMConstantPoolConstant(C, ID, Kind, PCAdj,
    144                                      ARMCP::no_modifier, false);
    145 }
    146 
    147 ARMConstantPoolConstant *
    148 ARMConstantPoolConstant::Create(const Constant *C, unsigned ID,
    149                                 ARMCP::ARMCPKind Kind, unsigned char PCAdj,
    150                                 ARMCP::ARMCPModifier Modifier,
    151                                 bool AddCurrentAddress) {
    152   return new ARMConstantPoolConstant(C, ID, Kind, PCAdj, Modifier,
    153                                      AddCurrentAddress);
    154 }
    155 
    156 const GlobalValue *ARMConstantPoolConstant::getGV() const {
    157   return dyn_cast_or_null<GlobalValue>(CVal);
    158 }
    159 
    160 const BlockAddress *ARMConstantPoolConstant::getBlockAddress() const {
    161   return dyn_cast_or_null<BlockAddress>(CVal);
    162 }
    163 
    164 int ARMConstantPoolConstant::getExistingMachineCPValue(MachineConstantPool *CP,
    165                                                        unsigned Alignment) {
    166   return getExistingMachineCPValueImpl<ARMConstantPoolConstant>(CP, Alignment);
    167 }
    168 
    169 bool ARMConstantPoolConstant::hasSameValue(ARMConstantPoolValue *ACPV) {
    170   const ARMConstantPoolConstant *ACPC = dyn_cast<ARMConstantPoolConstant>(ACPV);
    171   return ACPC && ACPC->CVal == CVal && ARMConstantPoolValue::hasSameValue(ACPV);
    172 }
    173 
    174 void ARMConstantPoolConstant::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
    175   ID.AddPointer(CVal);
    176   ARMConstantPoolValue::addSelectionDAGCSEId(ID);
    177 }
    178 
    179 void ARMConstantPoolConstant::print(raw_ostream &O) const {
    180   O << CVal->getName();
    181   ARMConstantPoolValue::print(O);
    182 }
    183 
    184 //===----------------------------------------------------------------------===//
    185 // ARMConstantPoolSymbol
    186 //===----------------------------------------------------------------------===//
    187 
    188 ARMConstantPoolSymbol::ARMConstantPoolSymbol(LLVMContext &C, const char *s,
    189                                              unsigned id,
    190                                              unsigned char PCAdj,
    191                                              ARMCP::ARMCPModifier Modifier,
    192                                              bool AddCurrentAddress)
    193   : ARMConstantPoolValue(C, id, ARMCP::CPExtSymbol, PCAdj, Modifier,
    194                          AddCurrentAddress),
    195     S(s) {}
    196 
    197 ARMConstantPoolSymbol *
    198 ARMConstantPoolSymbol::Create(LLVMContext &C, const char *s,
    199                               unsigned ID, unsigned char PCAdj) {
    200   return new ARMConstantPoolSymbol(C, s, ID, PCAdj, ARMCP::no_modifier, false);
    201 }
    202 
    203 int ARMConstantPoolSymbol::getExistingMachineCPValue(MachineConstantPool *CP,
    204                                                      unsigned Alignment) {
    205   return getExistingMachineCPValueImpl<ARMConstantPoolSymbol>(CP, Alignment);
    206 }
    207 
    208 bool ARMConstantPoolSymbol::hasSameValue(ARMConstantPoolValue *ACPV) {
    209   const ARMConstantPoolSymbol *ACPS = dyn_cast<ARMConstantPoolSymbol>(ACPV);
    210   return ACPS && ACPS->S == S && ARMConstantPoolValue::hasSameValue(ACPV);
    211 }
    212 
    213 void ARMConstantPoolSymbol::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
    214   ID.AddString(S);
    215   ARMConstantPoolValue::addSelectionDAGCSEId(ID);
    216 }
    217 
    218 void ARMConstantPoolSymbol::print(raw_ostream &O) const {
    219   O << S;
    220   ARMConstantPoolValue::print(O);
    221 }
    222 
    223 //===----------------------------------------------------------------------===//
    224 // ARMConstantPoolMBB
    225 //===----------------------------------------------------------------------===//
    226 
    227 ARMConstantPoolMBB::ARMConstantPoolMBB(LLVMContext &C,
    228                                        const MachineBasicBlock *mbb,
    229                                        unsigned id, unsigned char PCAdj,
    230                                        ARMCP::ARMCPModifier Modifier,
    231                                        bool AddCurrentAddress)
    232   : ARMConstantPoolValue(C, id, ARMCP::CPMachineBasicBlock, PCAdj,
    233                          Modifier, AddCurrentAddress),
    234     MBB(mbb) {}
    235 
    236 ARMConstantPoolMBB *ARMConstantPoolMBB::Create(LLVMContext &C,
    237                                                const MachineBasicBlock *mbb,
    238                                                unsigned ID,
    239                                                unsigned char PCAdj) {
    240   return new ARMConstantPoolMBB(C, mbb, ID, PCAdj, ARMCP::no_modifier, false);
    241 }
    242 
    243 int ARMConstantPoolMBB::getExistingMachineCPValue(MachineConstantPool *CP,
    244                                                   unsigned Alignment) {
    245   return getExistingMachineCPValueImpl<ARMConstantPoolMBB>(CP, Alignment);
    246 }
    247 
    248 bool ARMConstantPoolMBB::hasSameValue(ARMConstantPoolValue *ACPV) {
    249   const ARMConstantPoolMBB *ACPMBB = dyn_cast<ARMConstantPoolMBB>(ACPV);
    250   return ACPMBB && ACPMBB->MBB == MBB &&
    251     ARMConstantPoolValue::hasSameValue(ACPV);
    252 }
    253 
    254 void ARMConstantPoolMBB::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
    255   ID.AddPointer(MBB);
    256   ARMConstantPoolValue::addSelectionDAGCSEId(ID);
    257 }
    258 
    259 void ARMConstantPoolMBB::print(raw_ostream &O) const {
    260   O << "BB#" << MBB->getNumber();
    261   ARMConstantPoolValue::print(O);
    262 }
    263