LLVM API Documentation
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 }