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/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     // 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   unsigned AlignMask = Alignment - 1;
    167   const std::vector<MachineConstantPoolEntry> Constants = CP->getConstants();
    168   for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
    169     if (Constants[i].isMachineConstantPoolEntry() &&
    170         (Constants[i].getAlignment() & AlignMask) == 0) {
    171       ARMConstantPoolValue *CPV =
    172         (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal;
    173       ARMConstantPoolConstant *APC = dyn_cast<ARMConstantPoolConstant>(CPV);
    174       if (!APC) continue;
    175       if (APC->CVal == CVal && equals(APC))
    176         return i;
    177     }
    178   }
    179 
    180   return -1;
    181 }
    182 
    183 bool ARMConstantPoolConstant::hasSameValue(ARMConstantPoolValue *ACPV) {
    184   const ARMConstantPoolConstant *ACPC = dyn_cast<ARMConstantPoolConstant>(ACPV);
    185   return ACPC && ACPC->CVal == CVal && ARMConstantPoolValue::hasSameValue(ACPV);
    186 }
    187 
    188 void ARMConstantPoolConstant::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
    189   ID.AddPointer(CVal);
    190   ARMConstantPoolValue::addSelectionDAGCSEId(ID);
    191 }
    192 
    193 void ARMConstantPoolConstant::print(raw_ostream &O) const {
    194   O << CVal->getName();
    195   ARMConstantPoolValue::print(O);
    196 }
    197 
    198 //===----------------------------------------------------------------------===//
    199 // ARMConstantPoolSymbol
    200 //===----------------------------------------------------------------------===//
    201 
    202 ARMConstantPoolSymbol::ARMConstantPoolSymbol(LLVMContext &C, const char *s,
    203                                              unsigned id,
    204                                              unsigned char PCAdj,
    205                                              ARMCP::ARMCPModifier Modifier,
    206                                              bool AddCurrentAddress)
    207   : ARMConstantPoolValue(C, id, ARMCP::CPExtSymbol, PCAdj, Modifier,
    208                          AddCurrentAddress),
    209     S(strdup(s)) {}
    210 
    211 ARMConstantPoolSymbol::~ARMConstantPoolSymbol() {
    212   free((void*)S);
    213 }
    214 
    215 ARMConstantPoolSymbol *
    216 ARMConstantPoolSymbol::Create(LLVMContext &C, const char *s,
    217                               unsigned ID, unsigned char PCAdj) {
    218   return new ARMConstantPoolSymbol(C, s, ID, PCAdj, ARMCP::no_modifier, false);
    219 }
    220 
    221 static bool CPV_streq(const char *S1, const char *S2) {
    222   if (S1 == S2)
    223     return true;
    224   if (S1 && S2 && strcmp(S1, S2) == 0)
    225     return true;
    226   return false;
    227 }
    228 
    229 int ARMConstantPoolSymbol::getExistingMachineCPValue(MachineConstantPool *CP,
    230                                                      unsigned Alignment) {
    231   unsigned AlignMask = Alignment - 1;
    232   const std::vector<MachineConstantPoolEntry> Constants = CP->getConstants();
    233   for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
    234     if (Constants[i].isMachineConstantPoolEntry() &&
    235         (Constants[i].getAlignment() & AlignMask) == 0) {
    236       ARMConstantPoolValue *CPV =
    237         (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal;
    238       ARMConstantPoolSymbol *APS = dyn_cast<ARMConstantPoolSymbol>(CPV);
    239       if (!APS) continue;
    240 
    241       if (CPV_streq(APS->S, S) && equals(APS))
    242         return i;
    243     }
    244   }
    245 
    246   return -1;
    247 }
    248 
    249 bool ARMConstantPoolSymbol::hasSameValue(ARMConstantPoolValue *ACPV) {
    250   const ARMConstantPoolSymbol *ACPS = dyn_cast<ARMConstantPoolSymbol>(ACPV);
    251   return ACPS && CPV_streq(ACPS->S, S) &&
    252     ARMConstantPoolValue::hasSameValue(ACPV);
    253 }
    254 
    255 void ARMConstantPoolSymbol::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
    256   ID.AddPointer(S);
    257   ARMConstantPoolValue::addSelectionDAGCSEId(ID);
    258 }
    259 
    260 void ARMConstantPoolSymbol::print(raw_ostream &O) const {
    261   O << S;
    262   ARMConstantPoolValue::print(O);
    263 }
    264 
    265 //===----------------------------------------------------------------------===//
    266 // ARMConstantPoolMBB
    267 //===----------------------------------------------------------------------===//
    268 
    269 ARMConstantPoolMBB::ARMConstantPoolMBB(LLVMContext &C,
    270                                        const MachineBasicBlock *mbb,
    271                                        unsigned id, unsigned char PCAdj,
    272                                        ARMCP::ARMCPModifier Modifier,
    273                                        bool AddCurrentAddress)
    274   : ARMConstantPoolValue(C, id, ARMCP::CPMachineBasicBlock, PCAdj,
    275                          Modifier, AddCurrentAddress),
    276     MBB(mbb) {}
    277 
    278 ARMConstantPoolMBB *ARMConstantPoolMBB::Create(LLVMContext &C,
    279                                                const MachineBasicBlock *mbb,
    280                                                unsigned ID,
    281                                                unsigned char PCAdj) {
    282   return new ARMConstantPoolMBB(C, mbb, ID, PCAdj, ARMCP::no_modifier, false);
    283 }
    284 
    285 int ARMConstantPoolMBB::getExistingMachineCPValue(MachineConstantPool *CP,
    286                                                   unsigned Alignment) {
    287   unsigned AlignMask = Alignment - 1;
    288   const std::vector<MachineConstantPoolEntry> Constants = CP->getConstants();
    289   for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
    290     if (Constants[i].isMachineConstantPoolEntry() &&
    291         (Constants[i].getAlignment() & AlignMask) == 0) {
    292       ARMConstantPoolValue *CPV =
    293         (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal;
    294       ARMConstantPoolMBB *APMBB = dyn_cast<ARMConstantPoolMBB>(CPV);
    295       if (!APMBB) continue;
    296 
    297       if (APMBB->MBB == MBB && equals(APMBB))
    298         return i;
    299     }
    300   }
    301 
    302   return -1;
    303 }
    304 
    305 bool ARMConstantPoolMBB::hasSameValue(ARMConstantPoolValue *ACPV) {
    306   const ARMConstantPoolMBB *ACPMBB = dyn_cast<ARMConstantPoolMBB>(ACPV);
    307   return ACPMBB && ACPMBB->MBB == MBB &&
    308     ARMConstantPoolValue::hasSameValue(ACPV);
    309 }
    310 
    311 void ARMConstantPoolMBB::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
    312   ID.AddPointer(MBB);
    313   ARMConstantPoolValue::addSelectionDAGCSEId(ID);
    314 }
    315 
    316 void ARMConstantPoolMBB::print(raw_ostream &O) const {
    317   O << "BB#" << MBB->getNumber();
    318   ARMConstantPoolValue::print(O);
    319 }
    320