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_PREL:    return "GOT_PREL";
00056   case ARMCP::GOTTPOFF:    return "gottpoff";
00057   case ARMCP::TPOFF:       return "tpoff";
00058   }
00059   llvm_unreachable("Unknown modifier!");
00060 }
00061 
00062 int ARMConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP,
00063                                                     unsigned Alignment) {
00064   llvm_unreachable("Shouldn't be calling this directly!");
00065 }
00066 
00067 void
00068 ARMConstantPoolValue::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
00069   ID.AddInteger(LabelId);
00070   ID.AddInteger(PCAdjust);
00071 }
00072 
00073 bool
00074 ARMConstantPoolValue::hasSameValue(ARMConstantPoolValue *ACPV) {
00075   if (ACPV->Kind == Kind &&
00076       ACPV->PCAdjust == PCAdjust &&
00077       ACPV->Modifier == Modifier) {
00078     if (ACPV->LabelId == LabelId)
00079       return true;
00080     // Two PC relative constpool entries containing the same GV address or
00081     // external symbols. FIXME: What about blockaddress?
00082     if (Kind == ARMCP::CPValue || Kind == ARMCP::CPExtSymbol)
00083       return true;
00084   }
00085   return false;
00086 }
00087 
00088 void ARMConstantPoolValue::dump() const {
00089   errs() << "  " << *this;
00090 }
00091 
00092 void ARMConstantPoolValue::print(raw_ostream &O) const {
00093   if (Modifier) O << "(" << getModifierText() << ")";
00094   if (PCAdjust != 0) {
00095     O << "-(LPC" << LabelId << "+" << (unsigned)PCAdjust;
00096     if (AddCurrentAddress) O << "-.";
00097     O << ")";
00098   }
00099 }
00100 
00101 //===----------------------------------------------------------------------===//
00102 // ARMConstantPoolConstant
00103 //===----------------------------------------------------------------------===//
00104 
00105 ARMConstantPoolConstant::ARMConstantPoolConstant(Type *Ty,
00106                                                  const Constant *C,
00107                                                  unsigned ID,
00108                                                  ARMCP::ARMCPKind Kind,
00109                                                  unsigned char PCAdj,
00110                                                  ARMCP::ARMCPModifier Modifier,
00111                                                  bool AddCurrentAddress)
00112   : ARMConstantPoolValue(Ty, ID, Kind, PCAdj, Modifier, AddCurrentAddress),
00113     CVal(C) {}
00114 
00115 ARMConstantPoolConstant::ARMConstantPoolConstant(const Constant *C,
00116                                                  unsigned ID,
00117                                                  ARMCP::ARMCPKind Kind,
00118                                                  unsigned char PCAdj,
00119                                                  ARMCP::ARMCPModifier Modifier,
00120                                                  bool AddCurrentAddress)
00121   : ARMConstantPoolValue((Type*)C->getType(), ID, Kind, PCAdj, Modifier,
00122                          AddCurrentAddress),
00123     CVal(C) {}
00124 
00125 ARMConstantPoolConstant *
00126 ARMConstantPoolConstant::Create(const Constant *C, unsigned ID) {
00127   return new ARMConstantPoolConstant(C, ID, ARMCP::CPValue, 0,
00128                                      ARMCP::no_modifier, false);
00129 }
00130 
00131 ARMConstantPoolConstant *
00132 ARMConstantPoolConstant::Create(const GlobalValue *GV,
00133                                 ARMCP::ARMCPModifier Modifier) {
00134   return new ARMConstantPoolConstant((Type*)Type::getInt32Ty(GV->getContext()),
00135                                      GV, 0, ARMCP::CPValue, 0,
00136                                      Modifier, false);
00137 }
00138 
00139 ARMConstantPoolConstant *
00140 ARMConstantPoolConstant::Create(const Constant *C, unsigned ID,
00141                                 ARMCP::ARMCPKind Kind, unsigned char PCAdj) {
00142   return new ARMConstantPoolConstant(C, ID, Kind, PCAdj,
00143                                      ARMCP::no_modifier, false);
00144 }
00145 
00146 ARMConstantPoolConstant *
00147 ARMConstantPoolConstant::Create(const Constant *C, unsigned ID,
00148                                 ARMCP::ARMCPKind Kind, unsigned char PCAdj,
00149                                 ARMCP::ARMCPModifier Modifier,
00150                                 bool AddCurrentAddress) {
00151   return new ARMConstantPoolConstant(C, ID, Kind, PCAdj, Modifier,
00152                                      AddCurrentAddress);
00153 }
00154 
00155 const GlobalValue *ARMConstantPoolConstant::getGV() const {
00156   return dyn_cast_or_null<GlobalValue>(CVal);
00157 }
00158 
00159 const BlockAddress *ARMConstantPoolConstant::getBlockAddress() const {
00160   return dyn_cast_or_null<BlockAddress>(CVal);
00161 }
00162 
00163 int ARMConstantPoolConstant::getExistingMachineCPValue(MachineConstantPool *CP,
00164                                                        unsigned Alignment) {
00165   return getExistingMachineCPValueImpl<ARMConstantPoolConstant>(CP, Alignment);
00166 }
00167 
00168 bool ARMConstantPoolConstant::hasSameValue(ARMConstantPoolValue *ACPV) {
00169   const ARMConstantPoolConstant *ACPC = dyn_cast<ARMConstantPoolConstant>(ACPV);
00170   return ACPC && ACPC->CVal == CVal && ARMConstantPoolValue::hasSameValue(ACPV);
00171 }
00172 
00173 void ARMConstantPoolConstant::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
00174   ID.AddPointer(CVal);
00175   ARMConstantPoolValue::addSelectionDAGCSEId(ID);
00176 }
00177 
00178 void ARMConstantPoolConstant::print(raw_ostream &O) const {
00179   O << CVal->getName();
00180   ARMConstantPoolValue::print(O);
00181 }
00182 
00183 //===----------------------------------------------------------------------===//
00184 // ARMConstantPoolSymbol
00185 //===----------------------------------------------------------------------===//
00186 
00187 ARMConstantPoolSymbol::ARMConstantPoolSymbol(LLVMContext &C, const char *s,
00188                                              unsigned id,
00189                                              unsigned char PCAdj,
00190                                              ARMCP::ARMCPModifier Modifier,
00191                                              bool AddCurrentAddress)
00192   : ARMConstantPoolValue(C, id, ARMCP::CPExtSymbol, PCAdj, Modifier,
00193                          AddCurrentAddress),
00194     S(s) {}
00195 
00196 ARMConstantPoolSymbol *
00197 ARMConstantPoolSymbol::Create(LLVMContext &C, const char *s,
00198                               unsigned ID, unsigned char PCAdj) {
00199   return new ARMConstantPoolSymbol(C, s, ID, PCAdj, ARMCP::no_modifier, false);
00200 }
00201 
00202 int ARMConstantPoolSymbol::getExistingMachineCPValue(MachineConstantPool *CP,
00203                                                      unsigned Alignment) {
00204   return getExistingMachineCPValueImpl<ARMConstantPoolSymbol>(CP, Alignment);
00205 }
00206 
00207 bool ARMConstantPoolSymbol::hasSameValue(ARMConstantPoolValue *ACPV) {
00208   const ARMConstantPoolSymbol *ACPS = dyn_cast<ARMConstantPoolSymbol>(ACPV);
00209   return ACPS && ACPS->S == S && ARMConstantPoolValue::hasSameValue(ACPV);
00210 }
00211 
00212 void ARMConstantPoolSymbol::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
00213   ID.AddString(S);
00214   ARMConstantPoolValue::addSelectionDAGCSEId(ID);
00215 }
00216 
00217 void ARMConstantPoolSymbol::print(raw_ostream &O) const {
00218   O << S;
00219   ARMConstantPoolValue::print(O);
00220 }
00221 
00222 //===----------------------------------------------------------------------===//
00223 // ARMConstantPoolMBB
00224 //===----------------------------------------------------------------------===//
00225 
00226 ARMConstantPoolMBB::ARMConstantPoolMBB(LLVMContext &C,
00227                                        const MachineBasicBlock *mbb,
00228                                        unsigned id, unsigned char PCAdj,
00229                                        ARMCP::ARMCPModifier Modifier,
00230                                        bool AddCurrentAddress)
00231   : ARMConstantPoolValue(C, id, ARMCP::CPMachineBasicBlock, PCAdj,
00232                          Modifier, AddCurrentAddress),
00233     MBB(mbb) {}
00234 
00235 ARMConstantPoolMBB *ARMConstantPoolMBB::Create(LLVMContext &C,
00236                                                const MachineBasicBlock *mbb,
00237                                                unsigned ID,
00238                                                unsigned char PCAdj) {
00239   return new ARMConstantPoolMBB(C, mbb, ID, PCAdj, ARMCP::no_modifier, false);
00240 }
00241 
00242 int ARMConstantPoolMBB::getExistingMachineCPValue(MachineConstantPool *CP,
00243                                                   unsigned Alignment) {
00244   return getExistingMachineCPValueImpl<ARMConstantPoolMBB>(CP, Alignment);
00245 }
00246 
00247 bool ARMConstantPoolMBB::hasSameValue(ARMConstantPoolValue *ACPV) {
00248   const ARMConstantPoolMBB *ACPMBB = dyn_cast<ARMConstantPoolMBB>(ACPV);
00249   return ACPMBB && ACPMBB->MBB == MBB &&
00250     ARMConstantPoolValue::hasSameValue(ACPV);
00251 }
00252 
00253 void ARMConstantPoolMBB::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
00254   ID.AddPointer(MBB);
00255   ARMConstantPoolValue::addSelectionDAGCSEId(ID);
00256 }
00257 
00258 void ARMConstantPoolMBB::print(raw_ostream &O) const {
00259   O << "BB#" << MBB->getNumber();
00260   ARMConstantPoolValue::print(O);
00261 }