Home | History | Annotate | Download | only in ARM
      1 //===- ARMConstantPoolValue.cpp - ARM constantpool value --------*- C++ -*-===//
      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/Constant.h"
     17 #include "llvm/Constants.h"
     18 #include "llvm/GlobalValue.h"
     19 #include "llvm/Type.h"
     20 #include "llvm/CodeGen/MachineBasicBlock.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   default: llvm_unreachable("Unknown modifier!");
     52     // FIXME: Are these case sensitive? It'd be nice to lower-case all the
     53     // strings if that's legal.
     54   case ARMCP::no_modifier: return "none";
     55   case ARMCP::TLSGD:       return "tlsgd";
     56   case ARMCP::GOT:         return "GOT";
     57   case ARMCP::GOTOFF:      return "GOTOFF";
     58   case ARMCP::GOTTPOFF:    return "gottpoff";
     59   case ARMCP::TPOFF:       return "tpoff";
     60   }
     61 }
     62 
     63 int ARMConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP,
     64                                                     unsigned Alignment) {
     65   assert(false && "Shouldn't be calling this directly!");
     66   return -1;
     67 }
     68 
     69 void
     70 ARMConstantPoolValue::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
     71   ID.AddInteger(LabelId);
     72   ID.AddInteger(PCAdjust);
     73 }
     74 
     75 bool
     76 ARMConstantPoolValue::hasSameValue(ARMConstantPoolValue *ACPV) {
     77   if (ACPV->Kind == Kind &&
     78       ACPV->PCAdjust == PCAdjust &&
     79       ACPV->Modifier == Modifier) {
     80     if (ACPV->LabelId == LabelId)
     81       return true;
     82     // Two PC relative constpool entries containing the same GV address or
     83     // external symbols. FIXME: What about blockaddress?
     84     if (Kind == ARMCP::CPValue || Kind == ARMCP::CPExtSymbol)
     85       return true;
     86   }
     87   return false;
     88 }
     89 
     90 void ARMConstantPoolValue::dump() const {
     91   errs() << "  " << *this;
     92 }
     93 
     94 void ARMConstantPoolValue::print(raw_ostream &O) const {
     95   if (Modifier) O << "(" << getModifierText() << ")";
     96   if (PCAdjust != 0) {
     97     O << "-(LPC" << LabelId << "+" << (unsigned)PCAdjust;
     98     if (AddCurrentAddress) O << "-.";
     99     O << ")";
    100   }
    101 }
    102 
    103 //===----------------------------------------------------------------------===//
    104 // ARMConstantPoolConstant
    105 //===----------------------------------------------------------------------===//
    106 
    107 ARMConstantPoolConstant::ARMConstantPoolConstant(Type *Ty,
    108                                                  const Constant *C,
    109                                                  unsigned ID,
    110                                                  ARMCP::ARMCPKind Kind,
    111                                                  unsigned char PCAdj,
    112                                                  ARMCP::ARMCPModifier Modifier,
    113                                                  bool AddCurrentAddress)
    114   : ARMConstantPoolValue(Ty, ID, Kind, PCAdj, Modifier, AddCurrentAddress),
    115     CVal(C) {}
    116 
    117 ARMConstantPoolConstant::ARMConstantPoolConstant(const Constant *C,
    118                                                  unsigned ID,
    119                                                  ARMCP::ARMCPKind Kind,
    120                                                  unsigned char PCAdj,
    121                                                  ARMCP::ARMCPModifier Modifier,
    122                                                  bool AddCurrentAddress)
    123   : ARMConstantPoolValue((Type*)C->getType(), ID, Kind, PCAdj, Modifier,
    124                          AddCurrentAddress),
    125     CVal(C) {}
    126 
    127 ARMConstantPoolConstant *
    128 ARMConstantPoolConstant::Create(const Constant *C, unsigned ID) {
    129   return new ARMConstantPoolConstant(C, ID, ARMCP::CPValue, 0,
    130                                      ARMCP::no_modifier, false);
    131 }
    132 
    133 ARMConstantPoolConstant *
    134 ARMConstantPoolConstant::Create(const GlobalValue *GV,
    135                                 ARMCP::ARMCPModifier Modifier) {
    136   return new ARMConstantPoolConstant((Type*)Type::getInt32Ty(GV->getContext()),
    137                                      GV, 0, ARMCP::CPValue, 0,
    138                                      Modifier, false);
    139 }
    140 
    141 ARMConstantPoolConstant *
    142 ARMConstantPoolConstant::Create(const Constant *C, unsigned ID,
    143                                 ARMCP::ARMCPKind Kind, unsigned char PCAdj) {
    144   return new ARMConstantPoolConstant(C, ID, Kind, PCAdj,
    145                                      ARMCP::no_modifier, false);
    146 }
    147 
    148 ARMConstantPoolConstant *
    149 ARMConstantPoolConstant::Create(const Constant *C, unsigned ID,
    150                                 ARMCP::ARMCPKind Kind, unsigned char PCAdj,
    151                                 ARMCP::ARMCPModifier Modifier,
    152                                 bool AddCurrentAddress) {
    153   return new ARMConstantPoolConstant(C, ID, Kind, PCAdj, Modifier,
    154                                      AddCurrentAddress);
    155 }
    156 
    157 const GlobalValue *ARMConstantPoolConstant::getGV() const {
    158   return dyn_cast_or_null<GlobalValue>(CVal);
    159 }
    160 
    161 const BlockAddress *ARMConstantPoolConstant::getBlockAddress() const {
    162   return dyn_cast_or_null<BlockAddress>(CVal);
    163 }
    164 
    165 int ARMConstantPoolConstant::getExistingMachineCPValue(MachineConstantPool *CP,
    166                                                        unsigned Alignment) {
    167   unsigned AlignMask = Alignment - 1;
    168   const std::vector<MachineConstantPoolEntry> Constants = CP->getConstants();
    169   for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
    170     if (Constants[i].isMachineConstantPoolEntry() &&
    171         (Constants[i].getAlignment() & AlignMask) == 0) {
    172       ARMConstantPoolValue *CPV =
    173         (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal;
    174       ARMConstantPoolConstant *APC = dyn_cast<ARMConstantPoolConstant>(CPV);
    175       if (!APC) continue;
    176       if (APC->CVal == CVal && equals(APC))
    177         return i;
    178     }
    179   }
    180 
    181   return -1;
    182 }
    183 
    184 bool ARMConstantPoolConstant::hasSameValue(ARMConstantPoolValue *ACPV) {
    185   const ARMConstantPoolConstant *ACPC = dyn_cast<ARMConstantPoolConstant>(ACPV);
    186   return ACPC && ACPC->CVal == CVal && ARMConstantPoolValue::hasSameValue(ACPV);
    187 }
    188 
    189 void ARMConstantPoolConstant::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
    190   ID.AddPointer(CVal);
    191   ARMConstantPoolValue::addSelectionDAGCSEId(ID);
    192 }
    193 
    194 void ARMConstantPoolConstant::print(raw_ostream &O) const {
    195   O << CVal->getName();
    196   ARMConstantPoolValue::print(O);
    197 }
    198 
    199 //===----------------------------------------------------------------------===//
    200 // ARMConstantPoolSymbol
    201 //===----------------------------------------------------------------------===//
    202 
    203 ARMConstantPoolSymbol::ARMConstantPoolSymbol(LLVMContext &C, const char *s,
    204                                              unsigned id,
    205                                              unsigned char PCAdj,
    206                                              ARMCP::ARMCPModifier Modifier,
    207                                              bool AddCurrentAddress)
    208   : ARMConstantPoolValue(C, id, ARMCP::CPExtSymbol, PCAdj, Modifier,
    209                          AddCurrentAddress),
    210     S(strdup(s)) {}
    211 
    212 ARMConstantPoolSymbol::~ARMConstantPoolSymbol() {
    213   free((void*)S);
    214 }
    215 
    216 ARMConstantPoolSymbol *
    217 ARMConstantPoolSymbol::Create(LLVMContext &C, const char *s,
    218                               unsigned ID, unsigned char PCAdj) {
    219   return new ARMConstantPoolSymbol(C, s, ID, PCAdj, ARMCP::no_modifier, false);
    220 }
    221 
    222 static bool CPV_streq(const char *S1, const char *S2) {
    223   if (S1 == S2)
    224     return true;
    225   if (S1 && S2 && strcmp(S1, S2) == 0)
    226     return true;
    227   return false;
    228 }
    229 
    230 int ARMConstantPoolSymbol::getExistingMachineCPValue(MachineConstantPool *CP,
    231                                                      unsigned Alignment) {
    232   unsigned AlignMask = Alignment - 1;
    233   const std::vector<MachineConstantPoolEntry> Constants = CP->getConstants();
    234   for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
    235     if (Constants[i].isMachineConstantPoolEntry() &&
    236         (Constants[i].getAlignment() & AlignMask) == 0) {
    237       ARMConstantPoolValue *CPV =
    238         (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal;
    239       ARMConstantPoolSymbol *APS = dyn_cast<ARMConstantPoolSymbol>(CPV);
    240       if (!APS) continue;
    241 
    242       if (CPV_streq(APS->S, S) && equals(APS))
    243         return i;
    244     }
    245   }
    246 
    247   return -1;
    248 }
    249 
    250 bool ARMConstantPoolSymbol::hasSameValue(ARMConstantPoolValue *ACPV) {
    251   const ARMConstantPoolSymbol *ACPS = dyn_cast<ARMConstantPoolSymbol>(ACPV);
    252   return ACPS && CPV_streq(ACPS->S, S) &&
    253     ARMConstantPoolValue::hasSameValue(ACPV);
    254 }
    255 
    256 void ARMConstantPoolSymbol::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
    257   ID.AddPointer(S);
    258   ARMConstantPoolValue::addSelectionDAGCSEId(ID);
    259 }
    260 
    261 void ARMConstantPoolSymbol::print(raw_ostream &O) const {
    262   O << S;
    263   ARMConstantPoolValue::print(O);
    264 }
    265 
    266 //===----------------------------------------------------------------------===//
    267 // ARMConstantPoolMBB
    268 //===----------------------------------------------------------------------===//
    269 
    270 ARMConstantPoolMBB::ARMConstantPoolMBB(LLVMContext &C,
    271                                        const MachineBasicBlock *mbb,
    272                                        unsigned id, unsigned char PCAdj,
    273                                        ARMCP::ARMCPModifier Modifier,
    274                                        bool AddCurrentAddress)
    275   : ARMConstantPoolValue(C, id, ARMCP::CPMachineBasicBlock, PCAdj,
    276                          Modifier, AddCurrentAddress),
    277     MBB(mbb) {}
    278 
    279 ARMConstantPoolMBB *ARMConstantPoolMBB::Create(LLVMContext &C,
    280                                                const MachineBasicBlock *mbb,
    281                                                unsigned ID,
    282                                                unsigned char PCAdj) {
    283   return new ARMConstantPoolMBB(C, mbb, ID, PCAdj, ARMCP::no_modifier, false);
    284 }
    285 
    286 int ARMConstantPoolMBB::getExistingMachineCPValue(MachineConstantPool *CP,
    287                                                   unsigned Alignment) {
    288   unsigned AlignMask = Alignment - 1;
    289   const std::vector<MachineConstantPoolEntry> Constants = CP->getConstants();
    290   for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
    291     if (Constants[i].isMachineConstantPoolEntry() &&
    292         (Constants[i].getAlignment() & AlignMask) == 0) {
    293       ARMConstantPoolValue *CPV =
    294         (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal;
    295       ARMConstantPoolMBB *APMBB = dyn_cast<ARMConstantPoolMBB>(CPV);
    296       if (!APMBB) continue;
    297 
    298       if (APMBB->MBB == MBB && equals(APMBB))
    299         return i;
    300     }
    301   }
    302 
    303   return -1;
    304 }
    305 
    306 bool ARMConstantPoolMBB::hasSameValue(ARMConstantPoolValue *ACPV) {
    307   const ARMConstantPoolMBB *ACPMBB = dyn_cast<ARMConstantPoolMBB>(ACPV);
    308   return ACPMBB && ACPMBB->MBB == MBB &&
    309     ARMConstantPoolValue::hasSameValue(ACPV);
    310 }
    311 
    312 void ARMConstantPoolMBB::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
    313   ID.AddPointer(MBB);
    314   ARMConstantPoolValue::addSelectionDAGCSEId(ID);
    315 }
    316 
    317 void ARMConstantPoolMBB::print(raw_ostream &O) const {
    318   ARMConstantPoolValue::print(O);
    319 }
    320