LLVM  mainline
ARMConstantPoolValue.cpp
Go to the documentation of this file.
00001 //===-- ARMConstantPoolValue.cpp - ARM constantpool value -----------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements the ARM specific constantpool value class.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "ARMConstantPoolValue.h"
00015 #include "llvm/ADT/FoldingSet.h"
00016 #include "llvm/CodeGen/MachineBasicBlock.h"
00017 #include "llvm/IR/Constant.h"
00018 #include "llvm/IR/Constants.h"
00019 #include "llvm/IR/GlobalValue.h"
00020 #include "llvm/IR/Type.h"
00021 #include "llvm/Support/raw_ostream.h"
00022 #include <cstdlib>
00023 using namespace llvm;
00024 
00025 //===----------------------------------------------------------------------===//
00026 // ARMConstantPoolValue
00027 //===----------------------------------------------------------------------===//
00028 
00029 ARMConstantPoolValue::ARMConstantPoolValue(Type *Ty, unsigned id,
00030                                            ARMCP::ARMCPKind kind,
00031                                            unsigned char PCAdj,
00032                                            ARMCP::ARMCPModifier modifier,
00033                                            bool addCurrentAddress)
00034   : MachineConstantPoolValue(Ty), LabelId(id), Kind(kind),
00035     PCAdjust(PCAdj), Modifier(modifier),
00036     AddCurrentAddress(addCurrentAddress) {}
00037 
00038 ARMConstantPoolValue::ARMConstantPoolValue(LLVMContext &C, unsigned id,
00039                                            ARMCP::ARMCPKind kind,
00040                                            unsigned char PCAdj,
00041                                            ARMCP::ARMCPModifier modifier,
00042                                            bool addCurrentAddress)
00043   : MachineConstantPoolValue((Type*)Type::getInt32Ty(C)),
00044     LabelId(id), Kind(kind), PCAdjust(PCAdj), Modifier(modifier),
00045     AddCurrentAddress(addCurrentAddress) {}
00046 
00047 ARMConstantPoolValue::~ARMConstantPoolValue() {}
00048 
00049 const char *ARMConstantPoolValue::getModifierText() const {
00050   switch (Modifier) {
00051     // FIXME: Are these case sensitive? It'd be nice to lower-case all the
00052     // strings if that's legal.
00053   case ARMCP::no_modifier: return "none";
00054   case ARMCP::TLSGD:       return "tlsgd";
00055   case ARMCP::GOT:         return "GOT";
00056   case ARMCP::GOTOFF:      return "GOTOFF";
00057   case ARMCP::GOTTPOFF:    return "gottpoff";
00058   case ARMCP::TPOFF:       return "tpoff";
00059   }
00060   llvm_unreachable("Unknown modifier!");
00061 }
00062 
00063 int ARMConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP,
00064                                                     unsigned Alignment) {
00065   llvm_unreachable("Shouldn't be calling this directly!");
00066 }
00067 
00068 void
00069 ARMConstantPoolValue::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
00070   ID.AddInteger(LabelId);
00071   ID.AddInteger(PCAdjust);
00072 }
00073 
00074 bool
00075 ARMConstantPoolValue::hasSameValue(ARMConstantPoolValue *ACPV) {
00076   if (ACPV->Kind == Kind &&
00077       ACPV->PCAdjust == PCAdjust &&
00078       ACPV->Modifier == Modifier) {
00079     if (ACPV->LabelId == LabelId)
00080       return true;
00081     // Two PC relative constpool entries containing the same GV address or
00082     // external symbols. FIXME: What about blockaddress?
00083     if (Kind == ARMCP::CPValue || Kind == ARMCP::CPExtSymbol)
00084       return true;
00085   }
00086   return false;
00087 }
00088 
00089 void ARMConstantPoolValue::dump() const {
00090   errs() << "  " << *this;
00091 }
00092 
00093 void ARMConstantPoolValue::print(raw_ostream &O) const {
00094   if (Modifier) O << "(" << getModifierText() << ")";
00095   if (PCAdjust != 0) {
00096     O << "-(LPC" << LabelId << "+" << (unsigned)PCAdjust;
00097     if (AddCurrentAddress) O << "-.";
00098     O << ")";
00099   }
00100 }
00101 
00102 //===----------------------------------------------------------------------===//
00103 // ARMConstantPoolConstant
00104 //===----------------------------------------------------------------------===//
00105 
00106 ARMConstantPoolConstant::ARMConstantPoolConstant(Type *Ty,
00107                                                  const Constant *C,
00108                                                  unsigned ID,
00109                                                  ARMCP::ARMCPKind Kind,
00110                                                  unsigned char PCAdj,
00111                                                  ARMCP::ARMCPModifier Modifier,
00112                                                  bool AddCurrentAddress)
00113   : ARMConstantPoolValue(Ty, ID, Kind, PCAdj, Modifier, AddCurrentAddress),
00114     CVal(C) {}
00115 
00116 ARMConstantPoolConstant::ARMConstantPoolConstant(const Constant *C,
00117                                                  unsigned ID,
00118                                                  ARMCP::ARMCPKind Kind,
00119                                                  unsigned char PCAdj,
00120                                                  ARMCP::ARMCPModifier Modifier,
00121                                                  bool AddCurrentAddress)
00122   : ARMConstantPoolValue((Type*)C->getType(), ID, Kind, PCAdj, Modifier,
00123                          AddCurrentAddress),
00124     CVal(C) {}
00125 
00126 ARMConstantPoolConstant *
00127 ARMConstantPoolConstant::Create(const Constant *C, unsigned ID) {
00128   return new ARMConstantPoolConstant(C, ID, ARMCP::CPValue, 0,
00129                                      ARMCP::no_modifier, false);
00130 }
00131 
00132 ARMConstantPoolConstant *
00133 ARMConstantPoolConstant::Create(const GlobalValue *GV,
00134                                 ARMCP::ARMCPModifier Modifier) {
00135   return new ARMConstantPoolConstant((Type*)Type::getInt32Ty(GV->getContext()),
00136                                      GV, 0, ARMCP::CPValue, 0,
00137                                      Modifier, false);
00138 }
00139 
00140 ARMConstantPoolConstant *
00141 ARMConstantPoolConstant::Create(const Constant *C, unsigned ID,
00142                                 ARMCP::ARMCPKind Kind, unsigned char PCAdj) {
00143   return new ARMConstantPoolConstant(C, ID, Kind, PCAdj,
00144                                      ARMCP::no_modifier, false);
00145 }
00146 
00147 ARMConstantPoolConstant *
00148 ARMConstantPoolConstant::Create(const Constant *C, unsigned ID,
00149                                 ARMCP::ARMCPKind Kind, unsigned char PCAdj,
00150                                 ARMCP::ARMCPModifier Modifier,
00151                                 bool AddCurrentAddress) {
00152   return new ARMConstantPoolConstant(C, ID, Kind, PCAdj, Modifier,
00153                                      AddCurrentAddress);
00154 }
00155 
00156 const GlobalValue *ARMConstantPoolConstant::getGV() const {
00157   return dyn_cast_or_null<GlobalValue>(CVal);
00158 }
00159 
00160 const BlockAddress *ARMConstantPoolConstant::getBlockAddress() const {
00161   return dyn_cast_or_null<BlockAddress>(CVal);
00162 }
00163 
00164 int ARMConstantPoolConstant::getExistingMachineCPValue(MachineConstantPool *CP,
00165                                                        unsigned Alignment) {
00166   return getExistingMachineCPValueImpl<ARMConstantPoolConstant>(CP, Alignment);
00167 }
00168 
00169 bool ARMConstantPoolConstant::hasSameValue(ARMConstantPoolValue *ACPV) {
00170   const ARMConstantPoolConstant *ACPC = dyn_cast<ARMConstantPoolConstant>(ACPV);
00171   return ACPC && ACPC->CVal == CVal && ARMConstantPoolValue::hasSameValue(ACPV);
00172 }
00173 
00174 void ARMConstantPoolConstant::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
00175   ID.AddPointer(CVal);
00176   ARMConstantPoolValue::addSelectionDAGCSEId(ID);
00177 }
00178 
00179 void ARMConstantPoolConstant::print(raw_ostream &O) const {
00180   O << CVal->getName();
00181   ARMConstantPoolValue::print(O);
00182 }
00183 
00184 //===----------------------------------------------------------------------===//
00185 // ARMConstantPoolSymbol
00186 //===----------------------------------------------------------------------===//
00187 
00188 ARMConstantPoolSymbol::ARMConstantPoolSymbol(LLVMContext &C, const char *s,
00189                                              unsigned id,
00190                                              unsigned char PCAdj,
00191                                              ARMCP::ARMCPModifier Modifier,
00192                                              bool AddCurrentAddress)
00193   : ARMConstantPoolValue(C, id, ARMCP::CPExtSymbol, PCAdj, Modifier,
00194                          AddCurrentAddress),
00195     S(s) {}
00196 
00197 ARMConstantPoolSymbol *
00198 ARMConstantPoolSymbol::Create(LLVMContext &C, const char *s,
00199                               unsigned ID, unsigned char PCAdj) {
00200   return new ARMConstantPoolSymbol(C, s, ID, PCAdj, ARMCP::no_modifier, false);
00201 }
00202 
00203 int ARMConstantPoolSymbol::getExistingMachineCPValue(MachineConstantPool *CP,
00204                                                      unsigned Alignment) {
00205   return getExistingMachineCPValueImpl<ARMConstantPoolSymbol>(CP, Alignment);
00206 }
00207 
00208 bool ARMConstantPoolSymbol::hasSameValue(ARMConstantPoolValue *ACPV) {
00209   const ARMConstantPoolSymbol *ACPS = dyn_cast<ARMConstantPoolSymbol>(ACPV);
00210   return ACPS && ACPS->S == S && ARMConstantPoolValue::hasSameValue(ACPV);
00211 }
00212 
00213 void ARMConstantPoolSymbol::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
00214   ID.AddString(S);
00215   ARMConstantPoolValue::addSelectionDAGCSEId(ID);
00216 }
00217 
00218 void ARMConstantPoolSymbol::print(raw_ostream &O) const {
00219   O << S;
00220   ARMConstantPoolValue::print(O);
00221 }
00222 
00223 //===----------------------------------------------------------------------===//
00224 // ARMConstantPoolMBB
00225 //===----------------------------------------------------------------------===//
00226 
00227 ARMConstantPoolMBB::ARMConstantPoolMBB(LLVMContext &C,
00228                                        const MachineBasicBlock *mbb,
00229                                        unsigned id, unsigned char PCAdj,
00230                                        ARMCP::ARMCPModifier Modifier,
00231                                        bool AddCurrentAddress)
00232   : ARMConstantPoolValue(C, id, ARMCP::CPMachineBasicBlock, PCAdj,
00233                          Modifier, AddCurrentAddress),
00234     MBB(mbb) {}
00235 
00236 ARMConstantPoolMBB *ARMConstantPoolMBB::Create(LLVMContext &C,
00237                                                const MachineBasicBlock *mbb,
00238                                                unsigned ID,
00239                                                unsigned char PCAdj) {
00240   return new ARMConstantPoolMBB(C, mbb, ID, PCAdj, ARMCP::no_modifier, false);
00241 }
00242 
00243 int ARMConstantPoolMBB::getExistingMachineCPValue(MachineConstantPool *CP,
00244                                                   unsigned Alignment) {
00245   return getExistingMachineCPValueImpl<ARMConstantPoolMBB>(CP, Alignment);
00246 }
00247 
00248 bool ARMConstantPoolMBB::hasSameValue(ARMConstantPoolValue *ACPV) {
00249   const ARMConstantPoolMBB *ACPMBB = dyn_cast<ARMConstantPoolMBB>(ACPV);
00250   return ACPMBB && ACPMBB->MBB == MBB &&
00251     ARMConstantPoolValue::hasSameValue(ACPV);
00252 }
00253 
00254 void ARMConstantPoolMBB::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
00255   ID.AddPointer(MBB);
00256   ARMConstantPoolValue::addSelectionDAGCSEId(ID);
00257 }
00258 
00259 void ARMConstantPoolMBB::print(raw_ostream &O) const {
00260   O << "BB#" << MBB->getNumber();
00261   ARMConstantPoolValue::print(O);
00262 }