OLD | NEW |
1 //===- subzero/src/IceGlobalInits.cpp - Global initializers ---------------===// | 1 //===- subzero/src/IceGlobalInits.cpp - Global declarations ---------------===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file implements the notion of global addresses and | 10 // This file implements the notion of function declarations, global |
11 // initializers in Subzero. | 11 // variable declarations, and the corresponding variable initializers |
| 12 // in Subzero. |
12 // | 13 // |
13 //===----------------------------------------------------------------------===// | 14 //===----------------------------------------------------------------------===// |
14 | 15 |
15 #include "llvm/ADT/STLExtras.h" | 16 #include "llvm/ADT/STLExtras.h" |
16 #include "llvm/IR/Function.h" | 17 #include "llvm/IR/Function.h" |
17 #include "llvm/IR/Value.h" | 18 #include "llvm/IR/Value.h" |
18 | 19 |
19 #include "IceDefs.h" | 20 #include "IceDefs.h" |
| 21 #include "IceGlobalContext.h" |
20 #include "IceGlobalInits.h" | 22 #include "IceGlobalInits.h" |
21 #include "IceTypes.h" | 23 #include "IceTypes.h" |
22 | 24 |
23 namespace { | 25 namespace { |
24 char hexdigit(unsigned X) { return X < 10 ? '0' + X : 'A' + X - 10; } | 26 char hexdigit(unsigned X) { return X < 10 ? '0' + X : 'A' + X - 10; } |
| 27 |
| 28 void dumpLinkage(Ice::Ostream &Stream, |
| 29 llvm::GlobalValue::LinkageTypes Linkage) { |
| 30 switch (Linkage) { |
| 31 case llvm::GlobalValue::ExternalLinkage: |
| 32 Stream << "external"; |
| 33 return; |
| 34 case llvm::GlobalValue::InternalLinkage: |
| 35 Stream << "internal"; |
| 36 return; |
| 37 default: |
| 38 break; |
| 39 } |
| 40 std::string Buffer; |
| 41 llvm::raw_string_ostream StrBuf(Buffer); |
| 42 StrBuf << "Unknown linkage value: " << Linkage; |
| 43 llvm::report_fatal_error(StrBuf.str()); |
25 } | 44 } |
26 | 45 |
| 46 void dumpCallingConv(Ice::Ostream &, llvm::CallingConv::ID CallingConv) { |
| 47 if (CallingConv == llvm::CallingConv::C) |
| 48 return; |
| 49 std::string Buffer; |
| 50 llvm::raw_string_ostream StrBuf(Buffer); |
| 51 StrBuf << "Unknown calling convention: " << CallingConv; |
| 52 llvm::report_fatal_error(StrBuf.str()); |
| 53 } |
| 54 |
| 55 } // end of anonymous namespace |
| 56 |
27 namespace Ice { | 57 namespace Ice { |
28 | 58 |
29 GlobalAddress::~GlobalAddress() { llvm::DeleteContainerPointers(Initializers); } | 59 FunctionDeclaration * |
| 60 FunctionDeclaration::create(GlobalContext *Ctx, const FuncSigType &Signature, |
| 61 llvm::CallingConv::ID CallingConv, |
| 62 llvm::GlobalValue::LinkageTypes Linkage, |
| 63 bool IsProto) { |
| 64 return Ctx->newFunctionDeclaration(&Signature, CallingConv, Linkage, IsProto); |
| 65 } |
30 | 66 |
31 void GlobalAddress::dumpType(Ostream &Stream) const { | 67 void FunctionDeclaration::dumpType(Ostream &Stream) const { |
| 68 Stream << Signature; |
| 69 } |
| 70 |
| 71 void FunctionDeclaration::dump(Ostream &Stream) const { |
| 72 if (IsProto) |
| 73 Stream << "declare "; |
| 74 ::dumpLinkage(Stream, Linkage); |
| 75 ::dumpCallingConv(Stream, CallingConv); |
| 76 Stream << Signature.getReturnType() << " @" << Name << "("; |
| 77 bool IsFirst = true; |
| 78 for (Type ArgTy : Signature.getArgList()) { |
| 79 if (IsFirst) |
| 80 IsFirst = false; |
| 81 else |
| 82 Stream << ", "; |
| 83 Stream << ArgTy; |
| 84 } |
| 85 Stream << ")"; |
| 86 } |
| 87 |
| 88 VariableDeclaration *VariableDeclaration::create(GlobalContext *Ctx) { |
| 89 return Ctx->newVariableDeclaration(); |
| 90 } |
| 91 |
| 92 VariableDeclaration::~VariableDeclaration() { |
| 93 llvm::DeleteContainerPointers(Initializers); |
| 94 } |
| 95 |
| 96 void VariableDeclaration::dumpType(Ostream &Stream) const { |
32 if (Initializers.size() == 1) { | 97 if (Initializers.size() == 1) { |
33 Initializers.front()->dumpType(Stream); | 98 Initializers.front()->dumpType(Stream); |
34 } else { | 99 } else { |
35 Stream << "<{ "; | 100 Stream << "<{ "; |
36 bool IsFirst = true; | 101 bool IsFirst = true; |
37 for (Initializer *Init : Initializers) { | 102 for (Initializer *Init : Initializers) { |
38 if (IsFirst) { | 103 if (IsFirst) { |
39 IsFirst = false; | 104 IsFirst = false; |
40 } else { | 105 } else { |
41 Stream << ", "; | 106 Stream << ", "; |
42 } | 107 } |
43 Init->dumpType(Stream); | 108 Init->dumpType(Stream); |
44 } | 109 } |
45 Stream << " }>"; | 110 Stream << " }>"; |
46 } | 111 } |
47 } | 112 } |
48 | 113 |
49 void GlobalAddress::dump(Ostream &Stream) const { | 114 void VariableDeclaration::dump(Ostream &Stream) const { |
50 Stream << "@" << getName() << " = internal " | 115 Stream << "@" << Name << " = internal " |
51 << (IsConstant ? "constant" : "global") << " "; | 116 << (IsConstant ? "constant" : "global") << " "; |
52 | 117 |
53 // Add initializer. | 118 // Add initializer. |
54 if (Initializers.size() == 1) { | 119 if (Initializers.size() == 1) { |
55 Initializers.front()->dump(Stream); | 120 Initializers.front()->dump(Stream); |
56 } else { | 121 } else { |
57 dumpType(Stream); | 122 dumpType(Stream); |
58 Stream << " <{ "; | 123 Stream << " <{ "; |
59 bool IsFirst = true; | 124 bool IsFirst = true; |
60 for (Initializer *Init : Initializers) { | 125 for (Initializer *Init : Initializers) { |
61 if (IsFirst) { | 126 if (IsFirst) { |
62 IsFirst = false; | 127 IsFirst = false; |
63 } else { | 128 } else { |
64 Stream << ", "; | 129 Stream << ", "; |
65 } | 130 } |
66 Init->dump(Stream); | 131 Init->dump(Stream); |
67 } | 132 } |
68 Stream << " }>"; | 133 Stream << " }>"; |
69 } | 134 } |
70 | 135 |
71 // Add alignment. | 136 // Add alignment. |
72 if (Alignment > 0) | 137 if (Alignment > 0) |
73 Stream << ", align " << Alignment; | 138 Stream << ", align " << Alignment; |
74 Stream << "\n"; | 139 Stream << "\n"; |
75 } | 140 } |
76 | 141 |
77 void GlobalAddress::Initializer::dumpType(Ostream &Stream) const { | 142 void VariableDeclaration::Initializer::dumpType(Ostream &Stream) const { |
78 Stream << "[" << getNumBytes() << " x " << Ice::IceType_i8 << "]"; | 143 Stream << "[" << getNumBytes() << " x " << Ice::IceType_i8 << "]"; |
79 } | 144 } |
80 | 145 |
81 void GlobalAddress::DataInitializer::dump(Ostream &Stream) const { | 146 void VariableDeclaration::DataInitializer::dump(Ostream &Stream) const { |
82 dumpType(Stream); | 147 dumpType(Stream); |
83 Stream << " c\""; | 148 Stream << " c\""; |
84 // Code taken from PrintEscapedString() in AsmWriter.cpp. Keep | 149 // Code taken from PrintEscapedString() in AsmWriter.cpp. Keep |
85 // the strings in the same format as the .ll file for practical | 150 // the strings in the same format as the .ll file for practical |
86 // diffing. | 151 // diffing. |
87 for (uint8_t C : Contents) { | 152 for (uint8_t C : Contents) { |
88 if (isprint(C) && C != '\\' && C != '"') | 153 if (isprint(C) && C != '\\' && C != '"') |
89 Stream << C; | 154 Stream << C; |
90 else | 155 else |
91 Stream << '\\' << hexdigit(C >> 4) << hexdigit(C & 0x0F); | 156 Stream << '\\' << hexdigit(C >> 4) << hexdigit(C & 0x0F); |
92 } | 157 } |
93 Stream << "\""; | 158 Stream << "\""; |
94 } | 159 } |
95 | 160 |
96 void GlobalAddress::ZeroInitializer::dump(Ostream &Stream) const { | 161 void VariableDeclaration::ZeroInitializer::dump(Ostream &Stream) const { |
97 dumpType(Stream); | 162 dumpType(Stream); |
98 Stream << " zeroinitializer"; | 163 Stream << " zeroinitializer"; |
99 } | 164 } |
100 | 165 |
101 IceString GlobalAddress::RelocInitializer::getName() const { | 166 void VariableDeclaration::RelocInitializer::dumpType(Ostream &Stream) const { |
102 switch (Address.getKind()) { | |
103 case FunctionRelocation: | |
104 return Address.getFunction()->getName(); | |
105 case GlobalAddressRelocation: | |
106 return Address.getGlobalAddr()->getName(); | |
107 default: | |
108 llvm::report_fatal_error("Malformed relocation address!"); | |
109 } | |
110 } | |
111 | |
112 void GlobalAddress::RelocInitializer::dumpType(Ostream &Stream) const { | |
113 Stream << Ice::IceType_i32; | 167 Stream << Ice::IceType_i32; |
114 } | 168 } |
115 | 169 |
116 void GlobalAddress::RelocInitializer::dump(Ostream &Stream) const { | 170 void VariableDeclaration::RelocInitializer::dump(Ostream &Stream) const { |
117 if (Offset != 0) { | 171 if (Offset != 0) { |
118 dumpType(Stream); | 172 dumpType(Stream); |
119 Stream << " add ("; | 173 Stream << " add ("; |
120 } | 174 } |
121 dumpType(Stream); | 175 dumpType(Stream); |
122 Stream << " ptrtoint ("; | 176 Stream << " ptrtoint ("; |
123 if (Address.getKind() == FunctionRelocation) { | 177 Declaration->dumpType(Stream); |
124 Stream << *Address.getFunction()->getType() << " @" | 178 Stream << "* @" << Declaration->getName() << " to "; |
125 << Address.getFunction()->getName(); | |
126 } else { | |
127 Address.getGlobalAddr()->dumpType(Stream); | |
128 Stream << "* @" << Address.getGlobalAddr()->getName(); | |
129 } | |
130 Stream << " to "; | |
131 dumpType(Stream); | 179 dumpType(Stream); |
132 Stream << ")"; | 180 Stream << ")"; |
133 if (Offset != 0) { | 181 if (Offset != 0) { |
134 Stream << ", "; | 182 Stream << ", "; |
135 dumpType(Stream); | 183 dumpType(Stream); |
136 Stream << " " << Offset << ")"; | 184 Stream << " " << Offset << ")"; |
137 } | 185 } |
138 } | 186 } |
139 } | 187 |
| 188 } // end of namespace Ice |
OLD | NEW |