xref: /aosp_15_r20/external/swiftshader/third_party/subzero/src/IceGlobalInits.cpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
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