LLVM API Documentation

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   unsigned AlignMask = Alignment - 1;
00167   const std::vector<MachineConstantPoolEntry> Constants = CP->getConstants();
00168   for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
00169     if (Constants[i].isMachineConstantPoolEntry() &&
00170         (Constants[i].getAlignment() & AlignMask) == 0) {
00171       ARMConstantPoolValue *CPV =
00172         (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal;
00173       ARMConstantPoolConstant *APC = dyn_cast<ARMConstantPoolConstant>(CPV);
00174       if (!APC) continue;
00175       if (APC->CVal == CVal && equals(APC))
00176         return i;
00177     }
00178   }
00179 
00180   return -1;
00181 }
00182 
00183 bool ARMConstantPoolConstant::hasSameValue(ARMConstantPoolValue *ACPV) {
00184   const ARMConstantPoolConstant *ACPC = dyn_cast<ARMConstantPoolConstant>(ACPV);
00185   return ACPC && ACPC->CVal == CVal && ARMConstantPoolValue::hasSameValue(ACPV);
00186 }
00187 
00188 void ARMConstantPoolConstant::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
00189   ID.AddPointer(CVal);
00190   ARMConstantPoolValue::addSelectionDAGCSEId(ID);
00191 }
00192 
00193 void ARMConstantPoolConstant::print(raw_ostream &O) const {
00194   O << CVal->getName();
00195   ARMConstantPoolValue::print(O);
00196 }
00197 
00198 //===----------------------------------------------------------------------===//
00199 // ARMConstantPoolSymbol
00200 //===----------------------------------------------------------------------===//
00201 
00202 ARMConstantPoolSymbol::ARMConstantPoolSymbol(LLVMContext &C, const char *s,
00203                                              unsigned id,
00204                                              unsigned char PCAdj,
00205                                              ARMCP::ARMCPModifier Modifier,
00206                                              bool AddCurrentAddress)
00207   : ARMConstantPoolValue(C, id, ARMCP::CPExtSymbol, PCAdj, Modifier,
00208                          AddCurrentAddress),
00209     S(s) {}
00210 
00211 ARMConstantPoolSymbol *
00212 ARMConstantPoolSymbol::Create(LLVMContext &C, const char *s,
00213                               unsigned ID, unsigned char PCAdj) {
00214   return new ARMConstantPoolSymbol(C, s, ID, PCAdj, ARMCP::no_modifier, false);
00215 }
00216 
00217 int ARMConstantPoolSymbol::getExistingMachineCPValue(MachineConstantPool *CP,
00218                                                      unsigned Alignment) {
00219   unsigned AlignMask = Alignment - 1;
00220   const std::vector<MachineConstantPoolEntry> Constants = CP->getConstants();
00221   for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
00222     if (Constants[i].isMachineConstantPoolEntry() &&
00223         (Constants[i].getAlignment() & AlignMask) == 0) {
00224       ARMConstantPoolValue *CPV =
00225         (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal;
00226       ARMConstantPoolSymbol *APS = dyn_cast<ARMConstantPoolSymbol>(CPV);
00227       if (!APS) continue;
00228 
00229       if (APS->S == S && equals(APS))
00230         return i;
00231     }
00232   }
00233 
00234   return -1;
00235 }
00236 
00237 bool ARMConstantPoolSymbol::hasSameValue(ARMConstantPoolValue *ACPV) {
00238   const ARMConstantPoolSymbol *ACPS = dyn_cast<ARMConstantPoolSymbol>(ACPV);
00239   return ACPS && ACPS->S == S && ARMConstantPoolValue::hasSameValue(ACPV);
00240 }
00241 
00242 void ARMConstantPoolSymbol::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
00243   ID.AddString(S);
00244   ARMConstantPoolValue::addSelectionDAGCSEId(ID);
00245 }
00246 
00247 void ARMConstantPoolSymbol::print(raw_ostream &O) const {
00248   O << S;
00249   ARMConstantPoolValue::print(O);
00250 }
00251 
00252 //===----------------------------------------------------------------------===//
00253 // ARMConstantPoolMBB
00254 //===----------------------------------------------------------------------===//
00255 
00256 ARMConstantPoolMBB::ARMConstantPoolMBB(LLVMContext &C,
00257                                        const MachineBasicBlock *mbb,
00258                                        unsigned id, unsigned char PCAdj,
00259                                        ARMCP::ARMCPModifier Modifier,
00260                                        bool AddCurrentAddress)
00261   : ARMConstantPoolValue(C, id, ARMCP::CPMachineBasicBlock, PCAdj,
00262                          Modifier, AddCurrentAddress),
00263     MBB(mbb) {}
00264 
00265 ARMConstantPoolMBB *ARMConstantPoolMBB::Create(LLVMContext &C,
00266                                                const MachineBasicBlock *mbb,
00267                                                unsigned ID,
00268                                                unsigned char PCAdj) {
00269   return new ARMConstantPoolMBB(C, mbb, ID, PCAdj, ARMCP::no_modifier, false);
00270 }
00271 
00272 int ARMConstantPoolMBB::getExistingMachineCPValue(MachineConstantPool *CP,
00273                                                   unsigned Alignment) {
00274   unsigned AlignMask = Alignment - 1;
00275   const std::vector<MachineConstantPoolEntry> Constants = CP->getConstants();
00276   for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
00277     if (Constants[i].isMachineConstantPoolEntry() &&
00278         (Constants[i].getAlignment() & AlignMask) == 0) {
00279       ARMConstantPoolValue *CPV =
00280         (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal;
00281       ARMConstantPoolMBB *APMBB = dyn_cast<ARMConstantPoolMBB>(CPV);
00282       if (!APMBB) continue;
00283 
00284       if (APMBB->MBB == MBB && equals(APMBB))
00285         return i;
00286     }
00287   }
00288 
00289   return -1;
00290 }
00291 
00292 bool ARMConstantPoolMBB::hasSameValue(ARMConstantPoolValue *ACPV) {
00293   const ARMConstantPoolMBB *ACPMBB = dyn_cast<ARMConstantPoolMBB>(ACPV);
00294   return ACPMBB && ACPMBB->MBB == MBB &&
00295     ARMConstantPoolValue::hasSameValue(ACPV);
00296 }
00297 
00298 void ARMConstantPoolMBB::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
00299   ID.AddPointer(MBB);
00300   ARMConstantPoolValue::addSelectionDAGCSEId(ID);
00301 }
00302 
00303 void ARMConstantPoolMBB::print(raw_ostream &O) const {
00304   O << "BB#" << MBB->getNumber();
00305   ARMConstantPoolValue::print(O);
00306 }