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   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(s) {}
    210 
    211 ARMConstantPoolSymbol *
    212 ARMConstantPoolSymbol::Create(LLVMContext &C, const char *s,
    213                               unsigned ID, unsigned char PCAdj) {
    214   return new ARMConstantPoolSymbol(C, s, ID, PCAdj, ARMCP::no_modifier, false);
    215 }
    216 
    217 int ARMConstantPoolSymbol::getExistingMachineCPValue(MachineConstantPool *CP,
    218                                                      unsigned Alignment) {
    219   unsigned AlignMask = Alignment - 1;
    220   const std::vector<MachineConstantPoolEntry> Constants = CP->getConstants();
    221   for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
    222     if (Constants[i].isMachineConstantPoolEntry() &&
    223         (Constants[i].getAlignment() & AlignMask) == 0) {
    224       ARMConstantPoolValue *CPV =
    225         (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal;
    226       ARMConstantPoolSymbol *APS = dyn_cast<ARMConstantPoolSymbol>(CPV);
    227       if (!APS) continue;
    228 
    229       if (APS->S == S && equals(APS))
    230         return i;
    231     }
    232   }
    233 
    234   return -1;
    235 }
    236 
    237 bool ARMConstantPoolSymbol::hasSameValue(ARMConstantPoolValue *ACPV) {
    238   const ARMConstantPoolSymbol *ACPS = dyn_cast<ARMConstantPoolSymbol>(ACPV);
    239   return ACPS && ACPS->S == S && ARMConstantPoolValue::hasSameValue(ACPV);
    240 }
    241 
    242 void ARMConstantPoolSymbol::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
    243   ID.AddString(S);
    244   ARMConstantPoolValue::addSelectionDAGCSEId(ID);
    245 }
    246 
    247 void ARMConstantPoolSymbol::print(raw_ostream &O) const {
    248   O << S;
    249   ARMConstantPoolValue::print(O);
    250 }
    251 
    252 //===----------------------------------------------------------------------===//
    253 // ARMConstantPoolMBB
    254 //===----------------------------------------------------------------------===//
    255 
    256 ARMConstantPoolMBB::ARMConstantPoolMBB(LLVMContext &C,
    257                                        const MachineBasicBlock *mbb,
    258                                        unsigned id, unsigned char PCAdj,
    259                                        ARMCP::ARMCPModifier Modifier,
    260                                        bool AddCurrentAddress)
    261   : ARMConstantPoolValue(C, id, ARMCP::CPMachineBasicBlock, PCAdj,
    262                          Modifier, AddCurrentAddress),
    263     MBB(mbb) {}
    264 
    265 ARMConstantPoolMBB *ARMConstantPoolMBB::Create(LLVMContext &C,
    266                                                const MachineBasicBlock *mbb,
    267                                                unsigned ID,
    268                                                unsigned char PCAdj) {
    269   return new ARMConstantPoolMBB(C, mbb, ID, PCAdj, ARMCP::no_modifier, false);
    270 }
    271 
    272 int ARMConstantPoolMBB::getExistingMachineCPValue(MachineConstantPool *CP,
    273                                                   unsigned Alignment) {
    274   unsigned AlignMask = Alignment - 1;
    275   const std::vector<MachineConstantPoolEntry> Constants = CP->getConstants();
    276   for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
    277     if (Constants[i].isMachineConstantPoolEntry() &&
    278         (Constants[i].getAlignment() & AlignMask) == 0) {
    279       ARMConstantPoolValue *CPV =
    280         (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal;
    281       ARMConstantPoolMBB *APMBB = dyn_cast<ARMConstantPoolMBB>(CPV);
    282       if (!APMBB) continue;
    283 
    284       if (APMBB->MBB == MBB && equals(APMBB))
    285         return i;
    286     }
    287   }
    288 
    289   return -1;
    290 }
    291 
    292 bool ARMConstantPoolMBB::hasSameValue(ARMConstantPoolValue *ACPV) {
    293   const ARMConstantPoolMBB *ACPMBB = dyn_cast<ARMConstantPoolMBB>(ACPV);
    294   return ACPMBB && ACPMBB->MBB == MBB &&
    295     ARMConstantPoolValue::hasSameValue(ACPV);
    296 }
    297 
    298 void ARMConstantPoolMBB::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
    299   ID.AddPointer(MBB);
    300   ARMConstantPoolValue::addSelectionDAGCSEId(ID);
    301 }
    302 
    303 void ARMConstantPoolMBB::print(raw_ostream &O) const {
    304   O << "BB#" << MBB->getNumber();
    305   ARMConstantPoolValue::print(O);
    306 }
    307