1*03ce13f7SAndroid Build Coastguard Worker //===- subzero/src/IceGlobalInits.cpp - Global declarations ---------------===//
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker // The Subzero Code Generator
4*03ce13f7SAndroid Build Coastguard Worker //
5*03ce13f7SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*03ce13f7SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*03ce13f7SAndroid Build Coastguard Worker //
8*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*03ce13f7SAndroid Build Coastguard Worker ///
10*03ce13f7SAndroid Build Coastguard Worker /// \file
11*03ce13f7SAndroid Build Coastguard Worker /// \brief Implements the notion of function declarations, global variable
12*03ce13f7SAndroid Build Coastguard Worker /// declarations, and the corresponding variable initializers in Subzero.
13*03ce13f7SAndroid Build Coastguard Worker ///
14*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
15*03ce13f7SAndroid Build Coastguard Worker
16*03ce13f7SAndroid Build Coastguard Worker #include "IceGlobalInits.h"
17*03ce13f7SAndroid Build Coastguard Worker
18*03ce13f7SAndroid Build Coastguard Worker #include "IceDefs.h"
19*03ce13f7SAndroid Build Coastguard Worker #include "IceGlobalContext.h"
20*03ce13f7SAndroid Build Coastguard Worker #include "IceTypes.h"
21*03ce13f7SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
22*03ce13f7SAndroid Build Coastguard Worker #include "llvm/IR/Function.h"
23*03ce13f7SAndroid Build Coastguard Worker #include "llvm/IR/Value.h"
24*03ce13f7SAndroid Build Coastguard Worker
25*03ce13f7SAndroid Build Coastguard Worker namespace {
hexdigit(unsigned X)26*03ce13f7SAndroid Build Coastguard Worker char hexdigit(unsigned X) { return X < 10 ? '0' + X : 'A' + X - 10; }
27*03ce13f7SAndroid Build Coastguard Worker
dumpLinkage(Ice::Ostream & Stream,llvm::GlobalValue::LinkageTypes Linkage)28*03ce13f7SAndroid Build Coastguard Worker void dumpLinkage(Ice::Ostream &Stream,
29*03ce13f7SAndroid Build Coastguard Worker llvm::GlobalValue::LinkageTypes Linkage) {
30*03ce13f7SAndroid Build Coastguard Worker if (!Ice::BuildDefs::dump())
31*03ce13f7SAndroid Build Coastguard Worker return;
32*03ce13f7SAndroid Build Coastguard Worker switch (Linkage) {
33*03ce13f7SAndroid Build Coastguard Worker case llvm::GlobalValue::ExternalLinkage:
34*03ce13f7SAndroid Build Coastguard Worker Stream << "external";
35*03ce13f7SAndroid Build Coastguard Worker return;
36*03ce13f7SAndroid Build Coastguard Worker case llvm::GlobalValue::InternalLinkage:
37*03ce13f7SAndroid Build Coastguard Worker Stream << "internal";
38*03ce13f7SAndroid Build Coastguard Worker return;
39*03ce13f7SAndroid Build Coastguard Worker default:
40*03ce13f7SAndroid Build Coastguard Worker break;
41*03ce13f7SAndroid Build Coastguard Worker }
42*03ce13f7SAndroid Build Coastguard Worker std::string Buffer;
43*03ce13f7SAndroid Build Coastguard Worker llvm::raw_string_ostream StrBuf(Buffer);
44*03ce13f7SAndroid Build Coastguard Worker StrBuf << "Unknown linkage value: " << Linkage;
45*03ce13f7SAndroid Build Coastguard Worker llvm::report_fatal_error(StrBuf.str());
46*03ce13f7SAndroid Build Coastguard Worker }
47*03ce13f7SAndroid Build Coastguard Worker
dumpCallingConv(Ice::Ostream &,llvm::CallingConv::ID CallingConv)48*03ce13f7SAndroid Build Coastguard Worker void dumpCallingConv(Ice::Ostream &, llvm::CallingConv::ID CallingConv) {
49*03ce13f7SAndroid Build Coastguard Worker if (!Ice::BuildDefs::dump())
50*03ce13f7SAndroid Build Coastguard Worker return;
51*03ce13f7SAndroid Build Coastguard Worker if (CallingConv == llvm::CallingConv::C)
52*03ce13f7SAndroid Build Coastguard Worker return;
53*03ce13f7SAndroid Build Coastguard Worker std::string Buffer;
54*03ce13f7SAndroid Build Coastguard Worker llvm::raw_string_ostream StrBuf(Buffer);
55*03ce13f7SAndroid Build Coastguard Worker StrBuf << "Unknown calling convention: " << CallingConv;
56*03ce13f7SAndroid Build Coastguard Worker llvm::report_fatal_error(StrBuf.str());
57*03ce13f7SAndroid Build Coastguard Worker }
58*03ce13f7SAndroid Build Coastguard Worker
59*03ce13f7SAndroid Build Coastguard Worker } // end of anonymous namespace
60*03ce13f7SAndroid Build Coastguard Worker
61*03ce13f7SAndroid Build Coastguard Worker namespace Ice {
62*03ce13f7SAndroid Build Coastguard Worker
validateTypeSignature() const63*03ce13f7SAndroid Build Coastguard Worker bool FunctionDeclaration::validateTypeSignature() const {
64*03ce13f7SAndroid Build Coastguard Worker for (SizeT i = 0; i < Signature.getNumArgs(); ++i) {
65*03ce13f7SAndroid Build Coastguard Worker if (!isCallParameterType(Signature.getArgType(i)))
66*03ce13f7SAndroid Build Coastguard Worker return false;
67*03ce13f7SAndroid Build Coastguard Worker }
68*03ce13f7SAndroid Build Coastguard Worker return isCallReturnType(Signature.getReturnType());
69*03ce13f7SAndroid Build Coastguard Worker }
70*03ce13f7SAndroid Build Coastguard Worker
71*03ce13f7SAndroid Build Coastguard Worker std::string
getTypeSignatureError(const GlobalContext * Ctx)72*03ce13f7SAndroid Build Coastguard Worker FunctionDeclaration::getTypeSignatureError(const GlobalContext *Ctx) {
73*03ce13f7SAndroid Build Coastguard Worker std::string Buffer;
74*03ce13f7SAndroid Build Coastguard Worker llvm::raw_string_ostream StrBuf(Buffer);
75*03ce13f7SAndroid Build Coastguard Worker StrBuf << "Invalid type signature for";
76*03ce13f7SAndroid Build Coastguard Worker StrBuf << " " << getName() << ": " << getSignature();
77*03ce13f7SAndroid Build Coastguard Worker return StrBuf.str();
78*03ce13f7SAndroid Build Coastguard Worker }
79*03ce13f7SAndroid Build Coastguard Worker
dumpType(Ostream & Stream) const80*03ce13f7SAndroid Build Coastguard Worker void FunctionDeclaration::dumpType(Ostream &Stream) const {
81*03ce13f7SAndroid Build Coastguard Worker if (!Ice::BuildDefs::dump())
82*03ce13f7SAndroid Build Coastguard Worker return;
83*03ce13f7SAndroid Build Coastguard Worker Stream << Signature;
84*03ce13f7SAndroid Build Coastguard Worker }
85*03ce13f7SAndroid Build Coastguard Worker
dump(Ostream & Stream) const86*03ce13f7SAndroid Build Coastguard Worker void FunctionDeclaration::dump(Ostream &Stream) const {
87*03ce13f7SAndroid Build Coastguard Worker if (!Ice::BuildDefs::dump())
88*03ce13f7SAndroid Build Coastguard Worker return;
89*03ce13f7SAndroid Build Coastguard Worker if (IsProto)
90*03ce13f7SAndroid Build Coastguard Worker Stream << "declare ";
91*03ce13f7SAndroid Build Coastguard Worker ::dumpLinkage(Stream, Linkage);
92*03ce13f7SAndroid Build Coastguard Worker ::dumpCallingConv(Stream, CallingConv);
93*03ce13f7SAndroid Build Coastguard Worker Stream << Signature.getReturnType() << " @" << Name << "(";
94*03ce13f7SAndroid Build Coastguard Worker bool IsFirst = true;
95*03ce13f7SAndroid Build Coastguard Worker for (Type ArgTy : Signature.getArgList()) {
96*03ce13f7SAndroid Build Coastguard Worker if (IsFirst)
97*03ce13f7SAndroid Build Coastguard Worker IsFirst = false;
98*03ce13f7SAndroid Build Coastguard Worker else
99*03ce13f7SAndroid Build Coastguard Worker Stream << ", ";
100*03ce13f7SAndroid Build Coastguard Worker Stream << ArgTy;
101*03ce13f7SAndroid Build Coastguard Worker }
102*03ce13f7SAndroid Build Coastguard Worker Stream << ")";
103*03ce13f7SAndroid Build Coastguard Worker }
104*03ce13f7SAndroid Build Coastguard Worker
dumpType(Ostream & Stream) const105*03ce13f7SAndroid Build Coastguard Worker void VariableDeclaration::dumpType(Ostream &Stream) const {
106*03ce13f7SAndroid Build Coastguard Worker if (!Ice::BuildDefs::dump())
107*03ce13f7SAndroid Build Coastguard Worker return;
108*03ce13f7SAndroid Build Coastguard Worker if (Initializers.size() == 1) {
109*03ce13f7SAndroid Build Coastguard Worker Initializers.front()->dumpType(Stream);
110*03ce13f7SAndroid Build Coastguard Worker } else {
111*03ce13f7SAndroid Build Coastguard Worker Stream << "<{ ";
112*03ce13f7SAndroid Build Coastguard Worker bool IsFirst = true;
113*03ce13f7SAndroid Build Coastguard Worker for (const auto *Init : Initializers) {
114*03ce13f7SAndroid Build Coastguard Worker if (IsFirst) {
115*03ce13f7SAndroid Build Coastguard Worker IsFirst = false;
116*03ce13f7SAndroid Build Coastguard Worker } else {
117*03ce13f7SAndroid Build Coastguard Worker Stream << ", ";
118*03ce13f7SAndroid Build Coastguard Worker }
119*03ce13f7SAndroid Build Coastguard Worker Init->dumpType(Stream);
120*03ce13f7SAndroid Build Coastguard Worker }
121*03ce13f7SAndroid Build Coastguard Worker Stream << " }>";
122*03ce13f7SAndroid Build Coastguard Worker }
123*03ce13f7SAndroid Build Coastguard Worker }
124*03ce13f7SAndroid Build Coastguard Worker
dump(Ostream & Stream) const125*03ce13f7SAndroid Build Coastguard Worker void VariableDeclaration::dump(Ostream &Stream) const {
126*03ce13f7SAndroid Build Coastguard Worker if (!Ice::BuildDefs::dump())
127*03ce13f7SAndroid Build Coastguard Worker return;
128*03ce13f7SAndroid Build Coastguard Worker Stream << "@" << Name << " = ";
129*03ce13f7SAndroid Build Coastguard Worker ::dumpLinkage(Stream, Linkage);
130*03ce13f7SAndroid Build Coastguard Worker Stream << " " << (IsConstant ? "constant" : "global") << " ";
131*03ce13f7SAndroid Build Coastguard Worker
132*03ce13f7SAndroid Build Coastguard Worker // Add initializer.
133*03ce13f7SAndroid Build Coastguard Worker if (Initializers.size() == 1) {
134*03ce13f7SAndroid Build Coastguard Worker Initializers.front()->dump(Stream);
135*03ce13f7SAndroid Build Coastguard Worker } else {
136*03ce13f7SAndroid Build Coastguard Worker dumpType(Stream);
137*03ce13f7SAndroid Build Coastguard Worker Stream << " <{ ";
138*03ce13f7SAndroid Build Coastguard Worker bool IsFirst = true;
139*03ce13f7SAndroid Build Coastguard Worker for (const auto *Init : Initializers) {
140*03ce13f7SAndroid Build Coastguard Worker if (IsFirst) {
141*03ce13f7SAndroid Build Coastguard Worker IsFirst = false;
142*03ce13f7SAndroid Build Coastguard Worker } else {
143*03ce13f7SAndroid Build Coastguard Worker Stream << ", ";
144*03ce13f7SAndroid Build Coastguard Worker }
145*03ce13f7SAndroid Build Coastguard Worker Init->dump(Stream);
146*03ce13f7SAndroid Build Coastguard Worker }
147*03ce13f7SAndroid Build Coastguard Worker Stream << " }>";
148*03ce13f7SAndroid Build Coastguard Worker }
149*03ce13f7SAndroid Build Coastguard Worker
150*03ce13f7SAndroid Build Coastguard Worker // Add alignment.
151*03ce13f7SAndroid Build Coastguard Worker if (Alignment > 0)
152*03ce13f7SAndroid Build Coastguard Worker Stream << ", align " << Alignment;
153*03ce13f7SAndroid Build Coastguard Worker Stream << "\n";
154*03ce13f7SAndroid Build Coastguard Worker }
155*03ce13f7SAndroid Build Coastguard Worker
dumpType(Ostream & Stream) const156*03ce13f7SAndroid Build Coastguard Worker void VariableDeclaration::Initializer::dumpType(Ostream &Stream) const {
157*03ce13f7SAndroid Build Coastguard Worker if (!Ice::BuildDefs::dump())
158*03ce13f7SAndroid Build Coastguard Worker return;
159*03ce13f7SAndroid Build Coastguard Worker Stream << "[" << getNumBytes() << " x " << Ice::IceType_i8 << "]";
160*03ce13f7SAndroid Build Coastguard Worker }
161*03ce13f7SAndroid Build Coastguard Worker
dump(Ostream & Stream) const162*03ce13f7SAndroid Build Coastguard Worker void VariableDeclaration::DataInitializer::dump(Ostream &Stream) const {
163*03ce13f7SAndroid Build Coastguard Worker if (!Ice::BuildDefs::dump())
164*03ce13f7SAndroid Build Coastguard Worker return;
165*03ce13f7SAndroid Build Coastguard Worker dumpType(Stream);
166*03ce13f7SAndroid Build Coastguard Worker Stream << " c\"";
167*03ce13f7SAndroid Build Coastguard Worker // Code taken from PrintEscapedString() in AsmWriter.cpp. Keep the strings in
168*03ce13f7SAndroid Build Coastguard Worker // the same format as the .ll file for practical diffing.
169*03ce13f7SAndroid Build Coastguard Worker for (SizeT i = 0; i < ContentsSize; ++i) {
170*03ce13f7SAndroid Build Coastguard Worker uint8_t C = Contents[i];
171*03ce13f7SAndroid Build Coastguard Worker if (isprint(C) && C != '\\' && C != '"')
172*03ce13f7SAndroid Build Coastguard Worker Stream << C;
173*03ce13f7SAndroid Build Coastguard Worker else
174*03ce13f7SAndroid Build Coastguard Worker Stream << '\\' << hexdigit(C >> 4) << hexdigit(C & 0x0F);
175*03ce13f7SAndroid Build Coastguard Worker }
176*03ce13f7SAndroid Build Coastguard Worker Stream << "\"";
177*03ce13f7SAndroid Build Coastguard Worker }
178*03ce13f7SAndroid Build Coastguard Worker
dump(Ostream & Stream) const179*03ce13f7SAndroid Build Coastguard Worker void VariableDeclaration::ZeroInitializer::dump(Ostream &Stream) const {
180*03ce13f7SAndroid Build Coastguard Worker if (!Ice::BuildDefs::dump())
181*03ce13f7SAndroid Build Coastguard Worker return;
182*03ce13f7SAndroid Build Coastguard Worker dumpType(Stream);
183*03ce13f7SAndroid Build Coastguard Worker Stream << " zeroinitializer";
184*03ce13f7SAndroid Build Coastguard Worker }
185*03ce13f7SAndroid Build Coastguard Worker
dumpType(Ostream & Stream) const186*03ce13f7SAndroid Build Coastguard Worker void VariableDeclaration::RelocInitializer::dumpType(Ostream &Stream) const {
187*03ce13f7SAndroid Build Coastguard Worker if (!Ice::BuildDefs::dump())
188*03ce13f7SAndroid Build Coastguard Worker return;
189*03ce13f7SAndroid Build Coastguard Worker Stream << Ice::IceType_i32;
190*03ce13f7SAndroid Build Coastguard Worker }
191*03ce13f7SAndroid Build Coastguard Worker
dump(Ostream & Stream) const192*03ce13f7SAndroid Build Coastguard Worker void VariableDeclaration::RelocInitializer::dump(Ostream &Stream) const {
193*03ce13f7SAndroid Build Coastguard Worker if (!Ice::BuildDefs::dump())
194*03ce13f7SAndroid Build Coastguard Worker return;
195*03ce13f7SAndroid Build Coastguard Worker const RelocOffsetT Offset = getOffset();
196*03ce13f7SAndroid Build Coastguard Worker if (Offset != 0) {
197*03ce13f7SAndroid Build Coastguard Worker dumpType(Stream);
198*03ce13f7SAndroid Build Coastguard Worker Stream << " add (";
199*03ce13f7SAndroid Build Coastguard Worker }
200*03ce13f7SAndroid Build Coastguard Worker dumpType(Stream);
201*03ce13f7SAndroid Build Coastguard Worker Stream << " ptrtoint (";
202*03ce13f7SAndroid Build Coastguard Worker Declaration->dumpType(Stream);
203*03ce13f7SAndroid Build Coastguard Worker Stream << "* @" << Declaration->getName() << " to ";
204*03ce13f7SAndroid Build Coastguard Worker dumpType(Stream);
205*03ce13f7SAndroid Build Coastguard Worker Stream << ")";
206*03ce13f7SAndroid Build Coastguard Worker if (Offset != 0) {
207*03ce13f7SAndroid Build Coastguard Worker Stream << ", ";
208*03ce13f7SAndroid Build Coastguard Worker dumpType(Stream);
209*03ce13f7SAndroid Build Coastguard Worker Stream << " " << Offset << ")";
210*03ce13f7SAndroid Build Coastguard Worker }
211*03ce13f7SAndroid Build Coastguard Worker }
212*03ce13f7SAndroid Build Coastguard Worker
213*03ce13f7SAndroid Build Coastguard Worker } // end of namespace Ice
214