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