blob: 259c62e2007a0244771720a8796c6202adf26616 [file] [log] [blame]
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001//===- subzero/src/PNaClTranslator.cpp - ICE from bitcode -----------------===//
2//
3// The Subzero Code Generator
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
Andrew Scull9612d322015-07-06 14:53:25 -07009///
10/// \file
11/// This file implements the PNaCl bitcode file to Ice, to machine code
12/// translator.
13///
Karl Schimpf8d7abae2014-07-07 14:50:30 -070014//===----------------------------------------------------------------------===//
15
John Porto67f8de92015-06-25 10:14:17 -070016#include "PNaClTranslator.h"
Karl Schimpf8d7abae2014-07-07 14:50:30 -070017
Karl Schimpf32817482014-12-15 09:52:26 -080018#include "IceAPInt.h"
19#include "IceAPFloat.h"
Jim Stichnotha18cc9c2014-09-30 19:10:22 -070020#include "IceCfg.h"
21#include "IceCfgNode.h"
22#include "IceClFlags.h"
23#include "IceDefs.h"
Karl Schimpfe3f64d02014-10-07 10:38:22 -070024#include "IceGlobalInits.h"
Jim Stichnotha18cc9c2014-09-30 19:10:22 -070025#include "IceInst.h"
26#include "IceOperand.h"
Jim Stichnoth98da9662015-06-27 06:38:08 -070027
28#pragma clang diagnostic push
29#pragma clang diagnostic ignored "-Wunused-parameter"
John Porto67f8de92015-06-25 10:14:17 -070030#include "llvm/ADT/SmallString.h"
31#include "llvm/Bitcode/NaCl/NaClBitcodeDecoders.h"
32#include "llvm/Bitcode/NaCl/NaClBitcodeDefs.h"
33#include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h"
34#include "llvm/Bitcode/NaCl/NaClBitcodeParser.h"
35#include "llvm/Bitcode/NaCl/NaClReaderWriter.h"
36#include "llvm/Support/Format.h"
37#include "llvm/Support/MemoryBuffer.h"
38#include "llvm/Support/raw_ostream.h"
Jim Stichnoth98da9662015-06-27 06:38:08 -070039#pragma clang diagnostic pop
Karl Schimpf8d7abae2014-07-07 14:50:30 -070040
Karl Schimpf8d7abae2014-07-07 14:50:30 -070041namespace {
Karl Schimpf9d98d792014-10-13 15:01:08 -070042using namespace llvm;
Karl Schimpf8d7abae2014-07-07 14:50:30 -070043
Karl Schimpf645aa1a2014-10-08 09:05:53 -070044// Models elements in the list of types defined in the types block.
45// These elements can be undefined, a (simple) type, or a function type
46// signature. Note that an extended type is undefined on construction.
47// Use methods setAsSimpleType and setAsFuncSigType to define
48// the extended type.
49class ExtendedType {
Karl Schimpf645aa1a2014-10-08 09:05:53 -070050 ExtendedType &operator=(const ExtendedType &Ty) = delete;
Jim Stichnothdd842db2015-01-27 12:53:53 -080051
Karl Schimpf645aa1a2014-10-08 09:05:53 -070052public:
53 /// Discriminator for LLVM-style RTTI.
54 enum TypeKind { Undefined, Simple, FuncSig };
55
Jim Stichnotheafb56c2015-06-22 10:35:22 -070056 ExtendedType() = default;
Jim Stichnoth7e571362015-01-09 11:43:26 -080057 ExtendedType(const ExtendedType &Ty) = default;
Karl Schimpf645aa1a2014-10-08 09:05:53 -070058
Jim Stichnotheafb56c2015-06-22 10:35:22 -070059 virtual ~ExtendedType() = default;
Karl Schimpf645aa1a2014-10-08 09:05:53 -070060
61 ExtendedType::TypeKind getKind() const { return Kind; }
Karl Schimpfaff9fa22014-10-29 14:32:07 -070062 void dump(Ice::Ostream &Stream) const;
Karl Schimpf645aa1a2014-10-08 09:05:53 -070063
64 /// Changes the extended type to a simple type with the given
65 /// value.
66 void setAsSimpleType(Ice::Type Ty) {
67 assert(Kind == Undefined);
68 Kind = Simple;
69 Signature.setReturnType(Ty);
70 }
71
72 /// Changes the extended type to an (empty) function signature type.
73 void setAsFunctionType() {
74 assert(Kind == Undefined);
75 Kind = FuncSig;
76 }
77
78protected:
79 // Note: For simple types, the return type of the signature will
80 // be used to hold the simple type.
81 Ice::FuncSigType Signature;
82
83private:
Jim Stichnotheafb56c2015-06-22 10:35:22 -070084 ExtendedType::TypeKind Kind = Undefined;
Karl Schimpf645aa1a2014-10-08 09:05:53 -070085};
86
87Ice::Ostream &operator<<(Ice::Ostream &Stream, const ExtendedType &Ty) {
Jim Stichnoth20b71f52015-06-24 15:52:24 -070088 if (!Ice::BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -080089 return Stream;
Karl Schimpfaff9fa22014-10-29 14:32:07 -070090 Ty.dump(Stream);
Karl Schimpf645aa1a2014-10-08 09:05:53 -070091 return Stream;
92}
93
94Ice::Ostream &operator<<(Ice::Ostream &Stream, ExtendedType::TypeKind Kind) {
Jim Stichnoth20b71f52015-06-24 15:52:24 -070095 if (!Ice::BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -080096 return Stream;
Karl Schimpf645aa1a2014-10-08 09:05:53 -070097 Stream << "ExtendedType::";
98 switch (Kind) {
99 case ExtendedType::Undefined:
100 Stream << "Undefined";
101 break;
102 case ExtendedType::Simple:
103 Stream << "Simple";
104 break;
105 case ExtendedType::FuncSig:
106 Stream << "FuncSig";
107 break;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700108 }
109 return Stream;
110}
111
112// Models an ICE type as an extended type.
113class SimpleExtendedType : public ExtendedType {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800114 SimpleExtendedType() = delete;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700115 SimpleExtendedType(const SimpleExtendedType &) = delete;
116 SimpleExtendedType &operator=(const SimpleExtendedType &) = delete;
Jim Stichnothdd842db2015-01-27 12:53:53 -0800117
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700118public:
119 Ice::Type getType() const { return Signature.getReturnType(); }
120
121 static bool classof(const ExtendedType *Ty) {
122 return Ty->getKind() == Simple;
123 }
124};
125
126// Models a function signature as an extended type.
127class FuncSigExtendedType : public ExtendedType {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800128 FuncSigExtendedType() = delete;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700129 FuncSigExtendedType(const FuncSigExtendedType &) = delete;
130 FuncSigExtendedType &operator=(const FuncSigExtendedType &) = delete;
Jim Stichnothdd842db2015-01-27 12:53:53 -0800131
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700132public:
133 const Ice::FuncSigType &getSignature() const { return Signature; }
134 void setReturnType(Ice::Type ReturnType) {
135 Signature.setReturnType(ReturnType);
136 }
137 void appendArgType(Ice::Type ArgType) { Signature.appendArgType(ArgType); }
138 static bool classof(const ExtendedType *Ty) {
139 return Ty->getKind() == FuncSig;
140 }
141};
142
Karl Schimpfaff9fa22014-10-29 14:32:07 -0700143void ExtendedType::dump(Ice::Ostream &Stream) const {
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700144 if (!Ice::BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800145 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700146 Stream << Kind;
147 switch (Kind) {
148 case Simple: {
149 Stream << " " << Signature.getReturnType();
150 break;
151 }
152 case FuncSig: {
153 Stream << " " << Signature;
154 }
155 default:
156 break;
157 }
158}
159
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800160class BlockParserBaseClass;
161
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700162// Top-level class to read PNaCl bitcode files, and translate to ICE.
163class TopLevelParser : public NaClBitcodeParser {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800164 TopLevelParser() = delete;
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700165 TopLevelParser(const TopLevelParser &) = delete;
166 TopLevelParser &operator=(const TopLevelParser &) = delete;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700167
168public:
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800169 TopLevelParser(Ice::Translator &Translator, NaClBitstreamCursor &Cursor,
170 Ice::ErrorCode &ErrorStatus)
171 : NaClBitcodeParser(Cursor), Translator(Translator),
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700172 ErrorStatus(ErrorStatus),
173 VariableDeclarations(new Ice::VariableDeclarationList()) {}
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700174
Jim Stichnothe587d942015-06-22 15:49:04 -0700175 ~TopLevelParser() override = default;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700176
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800177 Ice::Translator &getTranslator() const { return Translator; }
Karl Schimpfd6064a12014-08-27 15:34:58 -0700178
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800179 void setBlockParser(BlockParserBaseClass *NewBlockParser) {
180 BlockParser = NewBlockParser;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700181 }
182
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800183 /// Generates error with given Message, occurring at BitPosition
184 /// within the bitcode file. Always returns true.
Karl Schimpf17b1a132015-03-12 09:32:06 -0700185 bool ErrorAt(naclbitc::ErrorLevel Level, uint64_t BitPosition,
186 const std::string &Message) final;
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800187
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800188 /// Generates error message with respect to the current block parser.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700189 bool blockError(const std::string &Message);
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800190
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700191 /// Returns the number of errors found while parsing the bitcode
192 /// file.
193 unsigned getNumErrors() const { return NumErrors; }
194
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700195 /// Changes the size of the type list to the given size.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700196 void resizeTypeIDValues(size_t NewSize) { TypeIDValues.resize(NewSize); }
197
198 size_t getNumTypeIDValues() const { return TypeIDValues.size(); }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700199
Karl Schimpf6fcbddd2014-11-06 09:49:24 -0800200 /// Returns true if generation of Subzero IR is disabled.
201 bool isIRGenerationDisabled() const {
Karl Schimpfdf80eb82015-02-09 14:20:22 -0800202 return Translator.getFlags().getDisableIRGeneration();
Karl Schimpf6fcbddd2014-11-06 09:49:24 -0800203 }
204
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700205 /// Returns the undefined type associated with type ID.
206 /// Note: Returns extended type ready to be defined.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700207 ExtendedType *getTypeByIDForDefining(NaClBcIndexSize_t ID) {
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700208 // Get corresponding element, verifying the value is still undefined
209 // (and hence allowed to be defined).
210 ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Undefined);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700211 if (Ty)
212 return Ty;
Karl Schimpf74cd8832015-06-23 11:05:01 -0700213 if (ID >= TypeIDValues.size()) {
214 if (ID >= NaClBcIndexSize_t_Max) {
215 std::string Buffer;
216 raw_string_ostream StrBuf(Buffer);
217 StrBuf << "Can't define more than " << NaClBcIndexSize_t_Max
218 << " types\n";
219 blockError(StrBuf.str());
220 // Recover by using existing type slot.
221 return &TypeIDValues[0];
222 }
Jim Stichnothdd842db2015-01-27 12:53:53 -0800223 TypeIDValues.resize(ID + 1);
Karl Schimpf74cd8832015-06-23 11:05:01 -0700224 }
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700225 return &TypeIDValues[ID];
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700226 }
227
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700228 /// Returns the type associated with the given index.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700229 Ice::Type getSimpleTypeByID(NaClBcIndexSize_t ID) {
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700230 const ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Simple);
231 if (Ty == nullptr)
232 // Return error recovery value.
233 return Ice::IceType_void;
234 return cast<SimpleExtendedType>(Ty)->getType();
235 }
236
237 /// Returns the type signature associated with the given index.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700238 const Ice::FuncSigType &getFuncSigTypeByID(NaClBcIndexSize_t ID) {
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700239 const ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::FuncSig);
240 if (Ty == nullptr)
241 // Return error recovery value.
242 return UndefinedFuncSigType;
243 return cast<FuncSigExtendedType>(Ty)->getSignature();
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700244 }
245
246 /// Sets the next function ID to the given LLVM function.
Karl Schimpf9d98d792014-10-13 15:01:08 -0700247 void setNextFunctionID(Ice::FunctionDeclaration *Fcn) {
Karl Schimpf209318a2015-08-20 13:24:02 -0700248 FunctionDeclarations.push_back(Fcn);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700249 }
250
Karl Schimpfd6064a12014-08-27 15:34:58 -0700251 /// Returns the value id that should be associated with the the
252 /// current function block. Increments internal counters during call
253 /// so that it will be in correct position for next function block.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700254 NaClBcIndexSize_t getNextFunctionBlockValueID() {
Karl Schimpf209318a2015-08-20 13:24:02 -0700255 size_t NumDeclaredFunctions = FunctionDeclarations.size();
Karl Schimpf0c729c82015-01-28 10:58:25 -0800256 while (NextDefiningFunctionID < NumDeclaredFunctions &&
Karl Schimpf209318a2015-08-20 13:24:02 -0700257 FunctionDeclarations[NextDefiningFunctionID]->isProto())
Karl Schimpf0c729c82015-01-28 10:58:25 -0800258 ++NextDefiningFunctionID;
259 if (NextDefiningFunctionID >= NumDeclaredFunctions)
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800260 Fatal("More function blocks than defined function addresses");
Karl Schimpf0c729c82015-01-28 10:58:25 -0800261 return NextDefiningFunctionID++;
Karl Schimpfd6064a12014-08-27 15:34:58 -0700262 }
263
Karl Schimpf9d98d792014-10-13 15:01:08 -0700264 /// Returns the function associated with ID.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700265 Ice::FunctionDeclaration *getFunctionByID(NaClBcIndexSize_t ID) {
Karl Schimpf209318a2015-08-20 13:24:02 -0700266 if (ID < FunctionDeclarations.size())
267 return FunctionDeclarations[ID];
Karl Schimpf9d98d792014-10-13 15:01:08 -0700268 return reportGetFunctionByIDError(ID);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700269 }
270
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800271 /// Returns the constant associated with the given global value ID.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700272 Ice::Constant *getGlobalConstantByID(NaClBcIndexSize_t ID) {
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800273 assert(ID < ValueIDConstants.size());
274 return ValueIDConstants[ID];
Karl Schimpf9d98d792014-10-13 15:01:08 -0700275 }
276
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800277 /// Install names for all global values without names. Called after
278 /// the global value symbol table is processed, but before any
279 /// function blocks are processed.
280 void installGlobalNames() {
281 assert(VariableDeclarations);
282 installGlobalVarNames();
283 installFunctionNames();
284 }
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700285
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800286 void createValueIDs() {
287 assert(VariableDeclarations);
288 ValueIDConstants.reserve(VariableDeclarations->size() +
Karl Schimpf209318a2015-08-20 13:24:02 -0700289 FunctionDeclarations.size());
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800290 createValueIDsForFunctions();
291 createValueIDsForGlobalVars();
Karl Schimpf8df26f32014-09-19 09:33:26 -0700292 }
293
Karl Schimpf9d98d792014-10-13 15:01:08 -0700294 /// Returns the number of function declarations in the bitcode file.
Karl Schimpf209318a2015-08-20 13:24:02 -0700295 size_t getNumFunctionIDs() const { return FunctionDeclarations.size(); }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700296
Karl Schimpf9d98d792014-10-13 15:01:08 -0700297 /// Returns the number of global declarations (i.e. IDs) defined in
298 /// the bitcode file.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700299 size_t getNumGlobalIDs() const {
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800300 if (VariableDeclarations) {
Karl Schimpf209318a2015-08-20 13:24:02 -0700301 return FunctionDeclarations.size() + VariableDeclarations->size();
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800302 } else {
303 return ValueIDConstants.size();
304 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700305 }
306
Karl Schimpfaa0ce792015-08-07 09:28:57 -0700307 /// Adds the given global declaration to the end of the list of global
308 /// declarations.
309 void addGlobalDeclaration(Ice::VariableDeclaration *Decl) {
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800310 assert(VariableDeclarations);
Karl Schimpfaa0ce792015-08-07 09:28:57 -0700311 VariableDeclarations->push_back(Decl);
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700312 }
313
Karl Schimpf9d98d792014-10-13 15:01:08 -0700314 /// Returns the global variable declaration with the given index.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700315 Ice::VariableDeclaration *getGlobalVariableByID(NaClBcIndexSize_t Index) {
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800316 assert(VariableDeclarations);
317 if (Index < VariableDeclarations->size())
318 return VariableDeclarations->at(Index);
Karl Schimpf9d98d792014-10-13 15:01:08 -0700319 return reportGetGlobalVariableByIDError(Index);
320 }
321
322 /// Returns the global declaration (variable or function) with the
323 /// given Index.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700324 Ice::GlobalDeclaration *getGlobalDeclarationByID(NaClBcIndexSize_t Index) {
Karl Schimpf209318a2015-08-20 13:24:02 -0700325 size_t NumFunctionIds = FunctionDeclarations.size();
Karl Schimpf9d98d792014-10-13 15:01:08 -0700326 if (Index < NumFunctionIds)
327 return getFunctionByID(Index);
328 else
329 return getGlobalVariableByID(Index - NumFunctionIds);
330 }
331
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800332 /// Returns the list of parsed global variable
333 /// declarations. Releases ownership of the current list of global
334 /// variables. Note: only returns non-null pointer on first
335 /// call. All successive calls return a null pointer.
336 std::unique_ptr<Ice::VariableDeclarationList> getGlobalVariables() {
337 // Before returning, check that ValidIDConstants has already been
338 // built.
339 assert(!VariableDeclarations ||
340 VariableDeclarations->size() <= ValueIDConstants.size());
341 return std::move(VariableDeclarations);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700342 }
343
344private:
Karl Schimpfd6064a12014-08-27 15:34:58 -0700345 // The translator associated with the parser.
346 Ice::Translator &Translator;
Karl Schimpfb164d202014-07-11 10:26:34 -0700347 // The exit status that should be set to true if an error occurs.
Jim Stichnothfa4efea2015-01-27 05:06:03 -0800348 Ice::ErrorCode &ErrorStatus;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700349 // The number of errors reported.
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700350 unsigned NumErrors = 0;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700351 // The types associated with each type ID.
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700352 std::vector<ExtendedType> TypeIDValues;
Karl Schimpf0c729c82015-01-28 10:58:25 -0800353 // The set of functions (prototype and defined).
Karl Schimpf209318a2015-08-20 13:24:02 -0700354 Ice::FunctionDeclarationList FunctionDeclarations;
355 // The ID of the next possible defined function ID in FunctionDeclarations.
356 // FunctionDeclarations is filled first. It's the set of functions (either
357 // defined or isproto). Then function definitions are encountered/parsed and
358 // NextDefiningFunctionID is incremented to track the next actually-defined
359 // function.
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700360 size_t NextDefiningFunctionID = 0;
Karl Schimpf9d98d792014-10-13 15:01:08 -0700361 // The set of global variables.
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800362 std::unique_ptr<Ice::VariableDeclarationList> VariableDeclarations;
Karl Schimpf9d98d792014-10-13 15:01:08 -0700363 // Relocatable constants associated with global declarations.
Karl Schimpf209318a2015-08-20 13:24:02 -0700364 Ice::ConstantList ValueIDConstants;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700365 // Error recovery value to use when getFuncSigTypeByID fails.
366 Ice::FuncSigType UndefinedFuncSigType;
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800367 // The block parser currently being applied. Used for error
368 // reporting.
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700369 BlockParserBaseClass *BlockParser = nullptr;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700370
Jim Stichnoth8e8042c2014-09-25 17:51:47 -0700371 bool ParseBlock(unsigned BlockID) override;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700372
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700373 // Gets extended type associated with the given index, assuming the
374 // extended type is of the WantedKind. Generates error message if
375 // corresponding extended type of WantedKind can't be found, and
376 // returns nullptr.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700377 ExtendedType *getTypeByIDAsKind(NaClBcIndexSize_t ID,
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700378 ExtendedType::TypeKind WantedKind) {
379 ExtendedType *Ty = nullptr;
380 if (ID < TypeIDValues.size()) {
381 Ty = &TypeIDValues[ID];
382 if (Ty->getKind() == WantedKind)
383 return Ty;
384 }
385 // Generate an error message and set ErrorStatus.
386 this->reportBadTypeIDAs(ID, Ty, WantedKind);
387 return nullptr;
388 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700389
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800390 // Gives Decl a name if it doesn't already have one. Prefix and
391 // NameIndex are used to generate the name. NameIndex is
392 // automatically incremented if a new name is created. DeclType is
393 // literal text describing the type of name being created. Also
394 // generates warning if created names may conflict with named
395 // declarations.
396 void installDeclarationName(Ice::GlobalDeclaration *Decl,
397 const Ice::IceString &Prefix,
Karl Schimpf74cd8832015-06-23 11:05:01 -0700398 const char *DeclType,
399 NaClBcIndexSize_t &NameIndex) {
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800400 if (Decl->hasName()) {
401 Translator.checkIfUnnamedNameSafe(Decl->getName(), DeclType, Prefix);
402 } else {
403 Decl->setName(Translator.createUnnamedName(Prefix, NameIndex));
404 ++NameIndex;
405 }
406 }
407
408 // Installs names for global variables without names.
409 void installGlobalVarNames() {
410 assert(VariableDeclarations);
411 const Ice::IceString &GlobalPrefix =
412 getTranslator().getFlags().getDefaultGlobalPrefix();
413 if (!GlobalPrefix.empty()) {
Karl Schimpf74cd8832015-06-23 11:05:01 -0700414 NaClBcIndexSize_t NameIndex = 0;
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800415 for (Ice::VariableDeclaration *Var : *VariableDeclarations) {
416 installDeclarationName(Var, GlobalPrefix, "global", NameIndex);
417 }
418 }
419 }
420
421 // Installs names for functions without names.
422 void installFunctionNames() {
423 const Ice::IceString &FunctionPrefix =
424 getTranslator().getFlags().getDefaultFunctionPrefix();
425 if (!FunctionPrefix.empty()) {
Karl Schimpf74cd8832015-06-23 11:05:01 -0700426 NaClBcIndexSize_t NameIndex = 0;
Karl Schimpf209318a2015-08-20 13:24:02 -0700427 for (Ice::FunctionDeclaration *Func : FunctionDeclarations) {
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800428 installDeclarationName(Func, FunctionPrefix, "function", NameIndex);
429 }
430 }
431 }
432
433 // Builds a constant symbol named Name, suppressing name mangling if
434 // SuppressMangling. IsExternal is true iff the symbol is external.
435 Ice::Constant *getConstantSym(const Ice::IceString &Name,
436 bool SuppressMangling, bool IsExternal) const {
437 if (IsExternal) {
438 return getTranslator().getContext()->getConstantExternSym(Name);
439 } else {
440 const Ice::RelocOffsetT Offset = 0;
441 return getTranslator().getContext()->getConstantSym(Offset, Name,
442 SuppressMangling);
443 }
444 }
445
446 // Converts function declarations into constant value IDs.
447 void createValueIDsForFunctions() {
Karl Schimpf209318a2015-08-20 13:24:02 -0700448 for (const Ice::FunctionDeclaration *Func : FunctionDeclarations) {
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800449 Ice::Constant *C = nullptr;
450 if (!isIRGenerationDisabled()) {
451 C = getConstantSym(Func->getName(), Func->getSuppressMangling(),
452 Func->isProto());
453 }
454 ValueIDConstants.push_back(C);
455 }
456 }
457
458 // Converts global variable declarations into constant value IDs.
459 void createValueIDsForGlobalVars() {
460 for (const Ice::VariableDeclaration *Decl : *VariableDeclarations) {
461 Ice::Constant *C = nullptr;
462 if (!isIRGenerationDisabled()) {
463 C = getConstantSym(Decl->getName(), Decl->getSuppressMangling(),
464 !Decl->hasInitializer());
465 }
466 ValueIDConstants.push_back(C);
467 }
468 }
469
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700470 // Reports that type ID is undefined, or not of the WantedType.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700471 void reportBadTypeIDAs(NaClBcIndexSize_t ID, const ExtendedType *Ty,
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700472 ExtendedType::TypeKind WantedType);
Karl Schimpfd6064a12014-08-27 15:34:58 -0700473
Karl Schimpf9d98d792014-10-13 15:01:08 -0700474 // Reports that there is no function declaration for ID. Returns an
475 // error recovery value to use.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700476 Ice::FunctionDeclaration *reportGetFunctionByIDError(NaClBcIndexSize_t ID);
Karl Schimpf9d98d792014-10-13 15:01:08 -0700477
478 // Reports that there is not global variable declaration for
479 // ID. Returns an error recovery value to use.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700480 Ice::VariableDeclaration *
481 reportGetGlobalVariableByIDError(NaClBcIndexSize_t Index);
Karl Schimpf9d98d792014-10-13 15:01:08 -0700482
Karl Schimpfd6064a12014-08-27 15:34:58 -0700483 // Reports that there is no corresponding ICE type for LLVMTy, and
Karl Schimpf74cd8832015-06-23 11:05:01 -0700484 // returns Ice::IceType_void.
Karl Schimpfd6064a12014-08-27 15:34:58 -0700485 Ice::Type convertToIceTypeError(Type *LLVMTy);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700486};
487
Karl Schimpf17b1a132015-03-12 09:32:06 -0700488bool TopLevelParser::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit,
489 const std::string &Message) {
Jim Stichnothfa4efea2015-01-27 05:06:03 -0800490 ErrorStatus.assign(Ice::EC_Bitcode);
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800491 ++NumErrors;
Karl Schimpf819d7b52015-01-22 10:00:07 -0800492 Ice::GlobalContext *Context = Translator.getContext();
Karl Schimpfd8b32892015-04-16 15:47:25 -0700493 { // Lock while printing out error message.
494 Ice::OstreamLocker L(Context);
Karl Schimpf2f67b922015-04-22 15:20:16 -0700495 raw_ostream &OldErrStream = setErrStream(Context->getStrError());
Karl Schimpfd8b32892015-04-16 15:47:25 -0700496 NaClBitcodeParser::ErrorAt(Level, Bit, Message);
497 setErrStream(OldErrStream);
498 }
Jan Voungf644a4b2015-03-19 11:57:52 -0700499 if (Level >= naclbitc::Error &&
500 !Translator.getFlags().getAllowErrorRecovery())
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800501 Fatal();
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800502 return true;
503}
504
Karl Schimpf74cd8832015-06-23 11:05:01 -0700505void TopLevelParser::reportBadTypeIDAs(NaClBcIndexSize_t ID,
506 const ExtendedType *Ty,
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700507 ExtendedType::TypeKind WantedType) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700508 std::string Buffer;
509 raw_string_ostream StrBuf(Buffer);
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700510 if (Ty == nullptr) {
511 StrBuf << "Can't find extended type for type id: " << ID;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700512 } else {
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700513 StrBuf << "Type id " << ID << " not " << WantedType << ". Found: " << *Ty;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700514 }
Karl Schimpf74cd8832015-06-23 11:05:01 -0700515 blockError(StrBuf.str());
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700516}
517
Karl Schimpf9d98d792014-10-13 15:01:08 -0700518Ice::FunctionDeclaration *
Karl Schimpf74cd8832015-06-23 11:05:01 -0700519TopLevelParser::reportGetFunctionByIDError(NaClBcIndexSize_t ID) {
Karl Schimpf9d98d792014-10-13 15:01:08 -0700520 std::string Buffer;
521 raw_string_ostream StrBuf(Buffer);
522 StrBuf << "Function index " << ID
523 << " not allowed. Out of range. Must be less than "
Karl Schimpf209318a2015-08-20 13:24:02 -0700524 << FunctionDeclarations.size();
Karl Schimpf74cd8832015-06-23 11:05:01 -0700525 blockError(StrBuf.str());
Karl Schimpf209318a2015-08-20 13:24:02 -0700526 if (!FunctionDeclarations.empty())
527 return FunctionDeclarations[0];
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800528 Fatal();
Karl Schimpf9d98d792014-10-13 15:01:08 -0700529}
530
531Ice::VariableDeclaration *
Karl Schimpf74cd8832015-06-23 11:05:01 -0700532TopLevelParser::reportGetGlobalVariableByIDError(NaClBcIndexSize_t Index) {
Karl Schimpf9d98d792014-10-13 15:01:08 -0700533 std::string Buffer;
534 raw_string_ostream StrBuf(Buffer);
535 StrBuf << "Global index " << Index
536 << " not allowed. Out of range. Must be less than "
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800537 << VariableDeclarations->size();
Karl Schimpf74cd8832015-06-23 11:05:01 -0700538 blockError(StrBuf.str());
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800539 if (!VariableDeclarations->empty())
540 return VariableDeclarations->at(0);
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800541 Fatal();
Karl Schimpf9d98d792014-10-13 15:01:08 -0700542}
543
Karl Schimpfd6064a12014-08-27 15:34:58 -0700544Ice::Type TopLevelParser::convertToIceTypeError(Type *LLVMTy) {
545 std::string Buffer;
546 raw_string_ostream StrBuf(Buffer);
547 StrBuf << "Invalid LLVM type: " << *LLVMTy;
548 Error(StrBuf.str());
549 return Ice::IceType_void;
550}
551
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700552// Base class for parsing blocks within the bitcode file. Note:
553// Because this is the base class of block parsers, we generate error
554// messages if ParseBlock or ParseRecord is not overridden in derived
555// classes.
556class BlockParserBaseClass : public NaClBitcodeParser {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800557 BlockParserBaseClass() = delete;
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800558 BlockParserBaseClass(const BlockParserBaseClass &) = delete;
559 BlockParserBaseClass &operator=(const BlockParserBaseClass &) = delete;
560
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700561public:
562 // Constructor for the top-level module block parser.
563 BlockParserBaseClass(unsigned BlockID, TopLevelParser *Context)
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800564 : NaClBitcodeParser(BlockID, Context), Context(Context) {
565 Context->setBlockParser(this);
566 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700567
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800568 ~BlockParserBaseClass() override { Context->setBlockParser(nullptr); }
569
570 // Returns the printable name of the type of block being parsed.
571 virtual const char *getBlockName() const {
572 // If this class is used, it is parsing an unknown block.
573 return "unknown";
574 }
575
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800576 // Generates an error Message with the Bit address prefixed to it.
Karl Schimpf17b1a132015-03-12 09:32:06 -0700577 bool ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit,
578 const std::string &Message) final;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700579
580protected:
581 // The context parser that contains the decoded state.
582 TopLevelParser *Context;
583
584 // Constructor for nested block parsers.
585 BlockParserBaseClass(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
586 : NaClBitcodeParser(BlockID, EnclosingParser),
587 Context(EnclosingParser->Context) {}
588
Karl Schimpfd6064a12014-08-27 15:34:58 -0700589 // Gets the translator associated with the bitcode parser.
Karl Schimpf6ff33d22014-09-22 10:28:42 -0700590 Ice::Translator &getTranslator() const { return Context->getTranslator(); }
591
592 const Ice::ClFlags &getFlags() const { return getTranslator().getFlags(); }
Karl Schimpfd6064a12014-08-27 15:34:58 -0700593
Karl Schimpf6fcbddd2014-11-06 09:49:24 -0800594 bool isIRGenerationDisabled() const {
Karl Schimpfdf80eb82015-02-09 14:20:22 -0800595 return getTranslator().getFlags().getDisableIRGeneration();
Karl Schimpf6fcbddd2014-11-06 09:49:24 -0800596 }
597
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700598 // Default implementation. Reports that block is unknown and skips
599 // its contents.
Jim Stichnoth8e8042c2014-09-25 17:51:47 -0700600 bool ParseBlock(unsigned BlockID) override;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700601
602 // Default implementation. Reports that the record is not
603 // understood.
Jim Stichnoth8e8042c2014-09-25 17:51:47 -0700604 void ProcessRecord() override;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700605
Karl Schimpfd6064a12014-08-27 15:34:58 -0700606 // Checks if the size of the record is Size. Return true if valid.
607 // Otherwise generates an error and returns false.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700608 bool isValidRecordSize(size_t Size, const char *RecordName) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700609 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
Karl Schimpfd6064a12014-08-27 15:34:58 -0700610 if (Values.size() == Size)
611 return true;
Karl Schimpf74cd8832015-06-23 11:05:01 -0700612 reportRecordSizeError(Size, RecordName, nullptr);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700613 return false;
614 }
615
Karl Schimpfd6064a12014-08-27 15:34:58 -0700616 // Checks if the size of the record is at least as large as the
617 // LowerLimit. Returns true if valid. Otherwise generates an error
618 // and returns false.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700619 bool isValidRecordSizeAtLeast(size_t LowerLimit, const char *RecordName) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700620 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
Karl Schimpfd6064a12014-08-27 15:34:58 -0700621 if (Values.size() >= LowerLimit)
622 return true;
Karl Schimpf74cd8832015-06-23 11:05:01 -0700623 reportRecordSizeError(LowerLimit, RecordName, "at least");
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700624 return false;
625 }
626
Karl Schimpfd6064a12014-08-27 15:34:58 -0700627 // Checks if the size of the record is no larger than the
628 // UpperLimit. Returns true if valid. Otherwise generates an error
629 // and returns false.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700630 bool isValidRecordSizeAtMost(size_t UpperLimit, const char *RecordName) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700631 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
Karl Schimpfd6064a12014-08-27 15:34:58 -0700632 if (Values.size() <= UpperLimit)
633 return true;
Karl Schimpf74cd8832015-06-23 11:05:01 -0700634 reportRecordSizeError(UpperLimit, RecordName, "no more than");
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700635 return false;
636 }
637
Karl Schimpfd6064a12014-08-27 15:34:58 -0700638 // Checks if the size of the record is at least as large as the
639 // LowerLimit, and no larger than the UpperLimit. Returns true if
640 // valid. Otherwise generates an error and returns false.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700641 bool isValidRecordSizeInRange(size_t LowerLimit, size_t UpperLimit,
Karl Schimpfd6064a12014-08-27 15:34:58 -0700642 const char *RecordName) {
643 return isValidRecordSizeAtLeast(LowerLimit, RecordName) ||
644 isValidRecordSizeAtMost(UpperLimit, RecordName);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700645 }
646
647private:
648 /// Generates a record size error. ExpectedSize is the number
649 /// of elements expected. RecordName is the name of the kind of
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700650 /// record that has incorrect size. ContextMessage (if not nullptr)
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700651 /// is appended to "record expects" to describe how ExpectedSize
652 /// should be interpreted.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700653 void reportRecordSizeError(size_t ExpectedSize, const char *RecordName,
Karl Schimpfd6064a12014-08-27 15:34:58 -0700654 const char *ContextMessage);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700655};
656
Karl Schimpf74cd8832015-06-23 11:05:01 -0700657bool TopLevelParser::blockError(const std::string &Message) {
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800658 if (BlockParser)
659 return BlockParser->Error(Message);
660 else
661 return Error(Message);
662}
663
664// Generates an error Message with the bit address prefixed to it.
Jan Voungf644a4b2015-03-19 11:57:52 -0700665bool BlockParserBaseClass::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit,
666 const std::string &Message) {
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800667 std::string Buffer;
668 raw_string_ostream StrBuf(Buffer);
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800669 // Note: If dump routines have been turned off, the error messages
Karl Schimpf2e7daef2015-01-09 13:04:13 -0800670 // will not be readable. Hence, replace with simple error. We also
671 // use the simple form for unit tests.
Karl Schimpfdf80eb82015-02-09 14:20:22 -0800672 if (getFlags().getGenerateUnitTestMessages()) {
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800673 StrBuf << "Invalid " << getBlockName() << " record: <" << Record.GetCode();
674 for (const uint64_t Val : Record.GetValues()) {
675 StrBuf << " " << Val;
676 }
677 StrBuf << ">";
Karl Schimpfdf80eb82015-02-09 14:20:22 -0800678 } else {
679 StrBuf << Message;
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800680 }
Karl Schimpf17b1a132015-03-12 09:32:06 -0700681 return Context->ErrorAt(Level, Bit, StrBuf.str());
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800682}
683
Karl Schimpf74cd8832015-06-23 11:05:01 -0700684void BlockParserBaseClass::reportRecordSizeError(size_t ExpectedSize,
Karl Schimpfd6064a12014-08-27 15:34:58 -0700685 const char *RecordName,
686 const char *ContextMessage) {
687 std::string Buffer;
688 raw_string_ostream StrBuf(Buffer);
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800689 const char *BlockName = getBlockName();
690 const char FirstChar = toupper(*BlockName);
691 StrBuf << FirstChar << (BlockName + 1) << " " << RecordName
692 << " record expects";
Karl Schimpfd6064a12014-08-27 15:34:58 -0700693 if (ContextMessage)
694 StrBuf << " " << ContextMessage;
695 StrBuf << " " << ExpectedSize << " argument";
696 if (ExpectedSize > 1)
697 StrBuf << "s";
698 StrBuf << ". Found: " << Record.GetValues().size();
699 Error(StrBuf.str());
700}
701
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700702bool BlockParserBaseClass::ParseBlock(unsigned BlockID) {
703 // If called, derived class doesn't know how to handle block.
704 // Report error and skip.
705 std::string Buffer;
706 raw_string_ostream StrBuf(Buffer);
707 StrBuf << "Don't know how to parse block id: " << BlockID;
708 Error(StrBuf.str());
709 SkipBlock();
710 return false;
711}
712
713void BlockParserBaseClass::ProcessRecord() {
714 // If called, derived class doesn't know how to handle.
715 std::string Buffer;
716 raw_string_ostream StrBuf(Buffer);
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800717 StrBuf << "Don't know how to process " << getBlockName()
718 << " record:" << Record;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700719 Error(StrBuf.str());
720}
721
722// Class to parse a types block.
723class TypesParser : public BlockParserBaseClass {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800724 TypesParser() = delete;
725 TypesParser(const TypesParser &) = delete;
726 TypesParser &operator=(const TypesParser &) = delete;
727
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700728public:
729 TypesParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
Karl Schimpf58455872014-11-03 11:29:39 -0800730 : BlockParserBaseClass(BlockID, EnclosingParser),
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700731 Timer(Ice::TimerStack::TT_parseTypes, getTranslator().getContext()) {}
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700732
Karl Schimpf74cd8832015-06-23 11:05:01 -0700733 ~TypesParser() override {
734 if (ExpectedNumTypes != Context->getNumTypeIDValues()) {
735 std::string Buffer;
736 raw_string_ostream StrBuf(Buffer);
737 StrBuf << "Types block expected " << ExpectedNumTypes
738 << " types but found: " << NextTypeId;
739 Error(StrBuf.str());
740 }
741 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700742
743private:
Karl Schimpf58455872014-11-03 11:29:39 -0800744 Ice::TimerMarker Timer;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700745 // The type ID that will be associated with the next type defining
746 // record in the types block.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700747 NaClBcIndexSize_t NextTypeId = 0;
748
749 // The expected number of types, based on record TYPE_CODE_NUMENTRY.
750 NaClBcIndexSize_t ExpectedNumTypes = 0;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700751
Jim Stichnoth8e8042c2014-09-25 17:51:47 -0700752 void ProcessRecord() override;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700753
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800754 const char *getBlockName() const override { return "type"; }
755
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700756 void setNextTypeIDAsSimpleType(Ice::Type Ty) {
757 Context->getTypeByIDForDefining(NextTypeId++)->setAsSimpleType(Ty);
758 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700759};
760
761void TypesParser::ProcessRecord() {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700762 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
763 switch (Record.GetCode()) {
Karl Schimpf74cd8832015-06-23 11:05:01 -0700764 case naclbitc::TYPE_CODE_NUMENTRY: {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700765 // NUMENTRY: [numentries]
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800766 if (!isValidRecordSize(1, "count"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700767 return;
Karl Schimpf74cd8832015-06-23 11:05:01 -0700768 uint64_t Size = Values[0];
769 if (Size > NaClBcIndexSize_t_Max) {
770 std::string Buffer;
771 raw_string_ostream StrBuf(Buffer);
772 StrBuf << "Size to big for count record: " << Size;
773 Error(StrBuf.str());
774 ExpectedNumTypes = NaClBcIndexSize_t_Max;
775 }
776 // The code double checks that Expected size and the actual size
777 // at the end of the block. To reduce allocations we preallocate
778 // the space.
779 //
780 // However, if the number is large, we suspect that the number
781 // is (possibly) incorrect. In that case, we preallocate a
782 // smaller space.
783 constexpr uint64_t DefaultLargeResizeValue = 1000000;
784 Context->resizeTypeIDValues(std::min(Size, DefaultLargeResizeValue));
785 ExpectedNumTypes = Size;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700786 return;
Karl Schimpf74cd8832015-06-23 11:05:01 -0700787 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700788 case naclbitc::TYPE_CODE_VOID:
789 // VOID
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800790 if (!isValidRecordSize(0, "void"))
Karl Schimpfd6064a12014-08-27 15:34:58 -0700791 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700792 setNextTypeIDAsSimpleType(Ice::IceType_void);
793 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700794 case naclbitc::TYPE_CODE_FLOAT:
795 // FLOAT
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800796 if (!isValidRecordSize(0, "float"))
Karl Schimpfd6064a12014-08-27 15:34:58 -0700797 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700798 setNextTypeIDAsSimpleType(Ice::IceType_f32);
799 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700800 case naclbitc::TYPE_CODE_DOUBLE:
801 // DOUBLE
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800802 if (!isValidRecordSize(0, "double"))
Karl Schimpfd6064a12014-08-27 15:34:58 -0700803 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700804 setNextTypeIDAsSimpleType(Ice::IceType_f64);
805 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700806 case naclbitc::TYPE_CODE_INTEGER:
807 // INTEGER: [width]
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800808 if (!isValidRecordSize(1, "integer"))
Karl Schimpfd6064a12014-08-27 15:34:58 -0700809 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700810 switch (Values[0]) {
811 case 1:
812 setNextTypeIDAsSimpleType(Ice::IceType_i1);
813 return;
814 case 8:
815 setNextTypeIDAsSimpleType(Ice::IceType_i8);
816 return;
817 case 16:
818 setNextTypeIDAsSimpleType(Ice::IceType_i16);
819 return;
820 case 32:
821 setNextTypeIDAsSimpleType(Ice::IceType_i32);
822 return;
823 case 64:
824 setNextTypeIDAsSimpleType(Ice::IceType_i64);
825 return;
826 default:
827 break;
828 }
829 {
Karl Schimpfd6064a12014-08-27 15:34:58 -0700830 std::string Buffer;
831 raw_string_ostream StrBuf(Buffer);
832 StrBuf << "Type integer record with invalid bitsize: " << Values[0];
833 Error(StrBuf.str());
Karl Schimpfd6064a12014-08-27 15:34:58 -0700834 }
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700835 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -0700836 case naclbitc::TYPE_CODE_VECTOR: {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700837 // VECTOR: [numelts, eltty]
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800838 if (!isValidRecordSize(2, "vector"))
Karl Schimpfd6064a12014-08-27 15:34:58 -0700839 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700840 Ice::Type BaseTy = Context->getSimpleTypeByID(Values[1]);
841 Ice::SizeT Size = Values[0];
842 switch (BaseTy) {
843 case Ice::IceType_i1:
844 switch (Size) {
845 case 4:
846 setNextTypeIDAsSimpleType(Ice::IceType_v4i1);
847 return;
848 case 8:
849 setNextTypeIDAsSimpleType(Ice::IceType_v8i1);
850 return;
851 case 16:
852 setNextTypeIDAsSimpleType(Ice::IceType_v16i1);
853 return;
854 default:
855 break;
856 }
857 break;
858 case Ice::IceType_i8:
859 if (Size == 16) {
860 setNextTypeIDAsSimpleType(Ice::IceType_v16i8);
861 return;
862 }
863 break;
864 case Ice::IceType_i16:
865 if (Size == 8) {
866 setNextTypeIDAsSimpleType(Ice::IceType_v8i16);
867 return;
868 }
869 break;
870 case Ice::IceType_i32:
871 if (Size == 4) {
872 setNextTypeIDAsSimpleType(Ice::IceType_v4i32);
873 return;
874 }
875 break;
876 case Ice::IceType_f32:
877 if (Size == 4) {
878 setNextTypeIDAsSimpleType(Ice::IceType_v4f32);
879 return;
880 }
881 break;
882 default:
883 break;
884 }
885 {
Karl Schimpfd6064a12014-08-27 15:34:58 -0700886 std::string Buffer;
887 raw_string_ostream StrBuf(Buffer);
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700888 StrBuf << "Invalid type vector record: <" << Values[0] << " x " << BaseTy
Karl Schimpfd6064a12014-08-27 15:34:58 -0700889 << ">";
890 Error(StrBuf.str());
Karl Schimpfd6064a12014-08-27 15:34:58 -0700891 }
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700892 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -0700893 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700894 case naclbitc::TYPE_CODE_FUNCTION: {
895 // FUNCTION: [vararg, retty, paramty x N]
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800896 if (!isValidRecordSizeAtLeast(2, "signature"))
Karl Schimpfd6064a12014-08-27 15:34:58 -0700897 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700898 if (Values[0])
899 Error("Function type can't define varargs");
900 ExtendedType *Ty = Context->getTypeByIDForDefining(NextTypeId++);
901 Ty->setAsFunctionType();
902 FuncSigExtendedType *FuncTy = cast<FuncSigExtendedType>(Ty);
903 FuncTy->setReturnType(Context->getSimpleTypeByID(Values[1]));
Karl Schimpf74cd8832015-06-23 11:05:01 -0700904 for (size_t i = 2, e = Values.size(); i != e; ++i) {
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700905 // Check that type void not used as argument type.
906 // Note: PNaCl restrictions can't be checked until we
907 // know the name, because we have to check for intrinsic signatures.
908 Ice::Type ArgTy = Context->getSimpleTypeByID(Values[i]);
909 if (ArgTy == Ice::IceType_void) {
910 std::string Buffer;
911 raw_string_ostream StrBuf(Buffer);
912 StrBuf << "Type for parameter " << (i - 1)
913 << " not valid. Found: " << ArgTy;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700914 ArgTy = Ice::IceType_i32;
915 }
916 FuncTy->appendArgType(ArgTy);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700917 }
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700918 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700919 }
920 default:
921 BlockParserBaseClass::ProcessRecord();
Karl Schimpfd6064a12014-08-27 15:34:58 -0700922 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700923 }
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700924 llvm_unreachable("Unknown type block record not processed!");
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700925}
926
Karl Schimpf9d98d792014-10-13 15:01:08 -0700927/// Parses the globals block (i.e. global variable declarations and
928/// corresponding initializers).
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700929class GlobalsParser : public BlockParserBaseClass {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800930 GlobalsParser() = delete;
931 GlobalsParser(const GlobalsParser &) = delete;
932 GlobalsParser &operator=(const GlobalsParser &) = delete;
933
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700934public:
935 GlobalsParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
Karl Schimpf58455872014-11-03 11:29:39 -0800936 : BlockParserBaseClass(BlockID, EnclosingParser),
937 Timer(Ice::TimerStack::TT_parseGlobals, getTranslator().getContext()),
Karl Schimpfaa0ce792015-08-07 09:28:57 -0700938 NumFunctionIDs(Context->getNumFunctionIDs()),
John Porto1bec8bc2015-06-22 10:51:13 -0700939 DummyGlobalVar(
940 Ice::VariableDeclaration::create(getTranslator().getContext())),
Karl Schimpf9d98d792014-10-13 15:01:08 -0700941 CurGlobalVar(DummyGlobalVar) {}
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700942
Jim Stichnothe587d942015-06-22 15:49:04 -0700943 ~GlobalsParser() final = default;
Karl Schimpf6fcbddd2014-11-06 09:49:24 -0800944
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800945 const char *getBlockName() const override { return "globals"; }
946
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700947private:
Karl Schimpfaa0ce792015-08-07 09:28:57 -0700948 typedef std::unordered_map<NaClBcIndexSize_t, Ice::VariableDeclaration *>
949 GlobalVarsMapType;
950
Karl Schimpf58455872014-11-03 11:29:39 -0800951 Ice::TimerMarker Timer;
Karl Schimpfaa0ce792015-08-07 09:28:57 -0700952
953 // Holds global variables generated/referenced in the global variables block.
954 GlobalVarsMapType GlobalVarsMap;
955
956 // Holds the number of defined function IDs.
957 NaClBcIndexSize_t NumFunctionIDs;
958
959 // Holds the specified number of global variables by the count record in
960 // the global variables block.
961 NaClBcIndexSize_t SpecifiedNumberVars = 0;
962
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700963 // Keeps track of how many initializers are expected for the global variable
Karl Schimpf9d98d792014-10-13 15:01:08 -0700964 // declaration being built.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700965 NaClBcIndexSize_t InitializersNeeded = 0;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700966
Karl Schimpf9d98d792014-10-13 15:01:08 -0700967 // The index of the next global variable declaration.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700968 NaClBcIndexSize_t NextGlobalID = 0;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700969
Karl Schimpf9d98d792014-10-13 15:01:08 -0700970 // Dummy global variable declaration to guarantee CurGlobalVar is
971 // always defined (allowing code to not need to check if
972 // CurGlobalVar is nullptr).
973 Ice::VariableDeclaration *DummyGlobalVar;
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700974
Karl Schimpf9d98d792014-10-13 15:01:08 -0700975 // Holds the current global variable declaration being built.
976 Ice::VariableDeclaration *CurGlobalVar;
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700977
Karl Schimpfaa0ce792015-08-07 09:28:57 -0700978 // Returns the global variable associated with the given Index.
979 Ice::VariableDeclaration *getGlobalVarByID(NaClBcIndexSize_t Index) {
980 Ice::VariableDeclaration *&Decl = GlobalVarsMap[Index];
981 if (Decl == nullptr)
982 Decl = Ice::VariableDeclaration::create(getTranslator().getContext());
983 return Decl;
984 }
985
986 // Returns the global declaration associated with the given index.
987 Ice::GlobalDeclaration *getGlobalDeclByID(NaClBcIndexSize_t Index) {
988 if (Index < NumFunctionIDs)
989 return Context->getFunctionByID(Index);
990 return getGlobalVarByID(Index - NumFunctionIDs);
991 }
992
993 // If global variables parsed correctly, install them into the top-level
994 // context.
995 void installGlobalVariables() {
996 // Verify specified number of globals matches number found.
997 size_t NumGlobals = GlobalVarsMap.size();
998 if (SpecifiedNumberVars != NumGlobals ||
999 SpecifiedNumberVars != NextGlobalID) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001000 std::string Buffer;
1001 raw_string_ostream StrBuf(Buffer);
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001002 StrBuf << getBlockName() << " block expects " << SpecifiedNumberVars
1003 << " global variables. Found: " << GlobalVarsMap.size();
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001004 Error(StrBuf.str());
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001005 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001006 }
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001007 // Install global variables into top-level context.
1008 for (size_t I = 0; I < NumGlobals; ++I)
1009 Context->addGlobalDeclaration(GlobalVarsMap[I]);
1010 }
1011
1012 void ExitBlock() override {
1013 verifyNoMissingInitializers();
1014 installGlobalVariables();
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001015 BlockParserBaseClass::ExitBlock();
1016 }
1017
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07001018 void ProcessRecord() override;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001019
Karl Schimpf9d98d792014-10-13 15:01:08 -07001020 // Checks if the number of initializers for the CurGlobalVar is the same as
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001021 // the number found in the bitcode file. If different, and error message is
1022 // generated, and the internal state of the parser is fixed so this condition
1023 // is no longer violated.
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001024 void verifyNoMissingInitializers() {
Karl Schimpf9d98d792014-10-13 15:01:08 -07001025 size_t NumInits = CurGlobalVar->getInitializers().size();
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001026 if (InitializersNeeded != NumInits) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001027 std::string Buffer;
1028 raw_string_ostream StrBuf(Buffer);
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001029 StrBuf << "Global variable @g" << NextGlobalID << " expected "
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001030 << InitializersNeeded << " initializer";
1031 if (InitializersNeeded > 1)
1032 StrBuf << "s";
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001033 StrBuf << ". Found: " << NumInits;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001034 Error(StrBuf.str());
Karl Schimpf9d98d792014-10-13 15:01:08 -07001035 InitializersNeeded = NumInits;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001036 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001037 }
1038};
1039
1040void GlobalsParser::ProcessRecord() {
1041 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1042 switch (Record.GetCode()) {
1043 case naclbitc::GLOBALVAR_COUNT:
1044 // COUNT: [n]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001045 if (!isValidRecordSize(1, "count"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001046 return;
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001047 if (SpecifiedNumberVars || NextGlobalID) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001048 Error("Globals count record not first in block.");
1049 return;
1050 }
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001051 SpecifiedNumberVars = Values[0];
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001052 return;
1053 case naclbitc::GLOBALVAR_VAR: {
1054 // VAR: [align, isconst]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001055 if (!isValidRecordSize(2, "variable"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001056 return;
1057 verifyNoMissingInitializers();
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001058 // Always build the global variable, even if IR generation is turned off.
1059 // This is needed because we need a placeholder in the top-level context
1060 // when no IR is generated.
1061 CurGlobalVar = getGlobalVarByID(NextGlobalID);
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08001062 if (!isIRGenerationDisabled()) {
1063 InitializersNeeded = 1;
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08001064 CurGlobalVar->setAlignment((1 << Values[0]) >> 1);
1065 CurGlobalVar->setIsConstant(Values[1] != 0);
1066 }
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001067 ++NextGlobalID;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001068 return;
1069 }
1070 case naclbitc::GLOBALVAR_COMPOUND:
1071 // COMPOUND: [size]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001072 if (!isValidRecordSize(1, "compound"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001073 return;
Karl Schimpf9d98d792014-10-13 15:01:08 -07001074 if (!CurGlobalVar->getInitializers().empty()) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001075 Error("Globals compound record not first initializer");
1076 return;
1077 }
1078 if (Values[0] < 2) {
1079 std::string Buffer;
1080 raw_string_ostream StrBuf(Buffer);
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001081 StrBuf << getBlockName()
1082 << " compound record size invalid. Found: " << Values[0];
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001083 Error(StrBuf.str());
1084 return;
1085 }
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08001086 if (isIRGenerationDisabled())
1087 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001088 InitializersNeeded = Values[0];
1089 return;
1090 case naclbitc::GLOBALVAR_ZEROFILL: {
1091 // ZEROFILL: [size]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001092 if (!isValidRecordSize(1, "zerofill"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001093 return;
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08001094 if (isIRGenerationDisabled())
1095 return;
Karl Schimpf9d98d792014-10-13 15:01:08 -07001096 CurGlobalVar->addInitializer(
John Porto1bec8bc2015-06-22 10:51:13 -07001097 Ice::VariableDeclaration::ZeroInitializer::create(Values[0]));
Karl Schimpf9d98d792014-10-13 15:01:08 -07001098 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001099 }
1100 case naclbitc::GLOBALVAR_DATA: {
1101 // DATA: [b0, b1, ...]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001102 if (!isValidRecordSizeAtLeast(1, "data"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001103 return;
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08001104 if (isIRGenerationDisabled())
1105 return;
Karl Schimpf9d98d792014-10-13 15:01:08 -07001106 CurGlobalVar->addInitializer(
John Porto1bec8bc2015-06-22 10:51:13 -07001107 Ice::VariableDeclaration::DataInitializer::create(Values));
Karl Schimpf9d98d792014-10-13 15:01:08 -07001108 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001109 }
1110 case naclbitc::GLOBALVAR_RELOC: {
1111 // RELOC: [val, [addend]]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001112 if (!isValidRecordSizeInRange(1, 2, "reloc"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001113 return;
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08001114 if (isIRGenerationDisabled())
1115 return;
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001116 NaClBcIndexSize_t Index = Values[0];
1117 NaClBcIndexSize_t IndexLimit = SpecifiedNumberVars + NumFunctionIDs;
1118 if (Index >= IndexLimit) {
1119 std::string Buffer;
1120 raw_string_ostream StrBuf(Buffer);
1121 StrBuf << "Relocation index " << Index << " to big. Expect index < "
1122 << IndexLimit;
1123 Error(StrBuf.str());
1124 }
Karl Schimpf74cd8832015-06-23 11:05:01 -07001125 uint64_t Offset = 0;
1126 if (Values.size() == 2) {
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001127 Offset = Values[1];
Karl Schimpf74cd8832015-06-23 11:05:01 -07001128 if (Offset > std::numeric_limits<uint32_t>::max()) {
1129 std::string Buffer;
1130 raw_string_ostream StrBuf(Buffer);
1131 StrBuf << "Addend of global reloc record too big: " << Offset;
1132 Error(StrBuf.str());
1133 }
1134 }
John Porto1bec8bc2015-06-22 10:51:13 -07001135 CurGlobalVar->addInitializer(
1136 Ice::VariableDeclaration::RelocInitializer::create(
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001137 getGlobalDeclByID(Index), Offset));
Karl Schimpf9d98d792014-10-13 15:01:08 -07001138 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001139 }
1140 default:
1141 BlockParserBaseClass::ProcessRecord();
1142 return;
1143 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001144}
1145
Karl Schimpfc132b762014-09-11 09:43:47 -07001146/// Base class for parsing a valuesymtab block in the bitcode file.
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001147class ValuesymtabParser : public BlockParserBaseClass {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001148 ValuesymtabParser() = delete;
Jim Stichnoth0795ba02014-10-01 14:23:01 -07001149 ValuesymtabParser(const ValuesymtabParser &) = delete;
1150 void operator=(const ValuesymtabParser &) = delete;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001151
1152public:
Karl Schimpfc132b762014-09-11 09:43:47 -07001153 ValuesymtabParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
1154 : BlockParserBaseClass(BlockID, EnclosingParser) {}
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001155
Jim Stichnothe587d942015-06-22 15:49:04 -07001156 ~ValuesymtabParser() override = default;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001157
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001158 const char *getBlockName() const override { return "valuesymtab"; }
1159
Karl Schimpfc132b762014-09-11 09:43:47 -07001160protected:
1161 typedef SmallString<128> StringType;
1162
1163 // Associates Name with the value defined by the given Index.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001164 virtual void setValueName(NaClBcIndexSize_t Index, StringType &Name) = 0;
Karl Schimpfc132b762014-09-11 09:43:47 -07001165
1166 // Associates Name with the value defined by the given Index;
Karl Schimpf74cd8832015-06-23 11:05:01 -07001167 virtual void setBbName(NaClBcIndexSize_t Index, StringType &Name) = 0;
Karl Schimpfc132b762014-09-11 09:43:47 -07001168
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001169private:
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07001170 void ProcessRecord() override;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001171
Karl Schimpf74cd8832015-06-23 11:05:01 -07001172 void convertToString(StringType &ConvertedName) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001173 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1174 for (size_t i = 1, e = Values.size(); i != e; ++i) {
1175 ConvertedName += static_cast<char>(Values[i]);
1176 }
1177 }
1178};
1179
1180void ValuesymtabParser::ProcessRecord() {
1181 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1182 StringType ConvertedName;
1183 switch (Record.GetCode()) {
1184 case naclbitc::VST_CODE_ENTRY: {
1185 // VST_ENTRY: [ValueId, namechar x N]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001186 if (!isValidRecordSizeAtLeast(2, "value entry"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001187 return;
Karl Schimpf74cd8832015-06-23 11:05:01 -07001188 convertToString(ConvertedName);
Karl Schimpfc132b762014-09-11 09:43:47 -07001189 setValueName(Values[0], ConvertedName);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001190 return;
1191 }
1192 case naclbitc::VST_CODE_BBENTRY: {
1193 // VST_BBENTRY: [BbId, namechar x N]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001194 if (!isValidRecordSizeAtLeast(2, "basic block entry"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001195 return;
Karl Schimpf74cd8832015-06-23 11:05:01 -07001196 convertToString(ConvertedName);
Karl Schimpfc132b762014-09-11 09:43:47 -07001197 setBbName(Values[0], ConvertedName);
1198 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001199 }
1200 default:
1201 break;
1202 }
1203 // If reached, don't know how to handle record.
1204 BlockParserBaseClass::ProcessRecord();
1205 return;
1206}
1207
Karl Schimpfd6064a12014-08-27 15:34:58 -07001208/// Parses function blocks in the bitcode file.
1209class FunctionParser : public BlockParserBaseClass {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001210 FunctionParser() = delete;
Jim Stichnoth0795ba02014-10-01 14:23:01 -07001211 FunctionParser(const FunctionParser &) = delete;
1212 FunctionParser &operator=(const FunctionParser &) = delete;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001213
1214public:
1215 FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
1216 : BlockParserBaseClass(BlockID, EnclosingParser),
Karl Schimpf58455872014-11-03 11:29:39 -08001217 Timer(Ice::TimerStack::TT_parseFunctions, getTranslator().getContext()),
Jim Stichnotheafb56c2015-06-22 10:35:22 -07001218 Func(nullptr), FcnId(Context->getNextFunctionBlockValueID()),
Karl Schimpf9d98d792014-10-13 15:01:08 -07001219 FuncDecl(Context->getFunctionByID(FcnId)),
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001220 CachedNumGlobalValueIDs(Context->getNumGlobalIDs()),
Jim Stichnotheafb56c2015-06-22 10:35:22 -07001221 NextLocalInstIndex(Context->getNumGlobalIDs()) {}
Jim Stichnoth8e928382015-02-02 17:03:08 -08001222
1223 bool convertFunction() {
1224 const Ice::TimerStackIdT StackID = Ice::GlobalContext::TSK_Funcs;
1225 Ice::TimerIdT TimerID = 0;
Karl Schimpfdf80eb82015-02-09 14:20:22 -08001226 const bool TimeThisFunction = getFlags().getTimeEachFunction();
Jim Stichnoth8e928382015-02-02 17:03:08 -08001227 if (TimeThisFunction) {
1228 TimerID = getTranslator().getContext()->getTimerID(StackID,
1229 FuncDecl->getName());
1230 getTranslator().getContext()->pushTimer(TimerID, StackID);
1231 }
1232
Karl Schimpf209318a2015-08-20 13:24:02 -07001233 // Note: The Cfg is created, even when IR generation is disabled. This
1234 // is done to install a CfgLocalAllocator for various internal containers.
1235 Func = Ice::Cfg::create(getTranslator().getContext(),
1236 getTranslator().getNextSequenceNumber());
Jim Stichnoth8e928382015-02-02 17:03:08 -08001237 Ice::Cfg::setCurrentCfg(Func.get());
1238
Karl Schimpf9d98d792014-10-13 15:01:08 -07001239 // TODO(kschimpf) Clean up API to add a function signature to
1240 // a CFG.
1241 const Ice::FuncSigType &Signature = FuncDecl->getSignature();
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08001242 if (isIRGenerationDisabled()) {
1243 CurrentNode = nullptr;
1244 for (Ice::Type ArgType : Signature.getArgList()) {
1245 (void)ArgType;
1246 setNextLocalInstIndex(nullptr);
1247 }
1248 } else {
1249 Func->setFunctionName(FuncDecl->getName());
1250 Func->setReturnType(Signature.getReturnType());
1251 Func->setInternal(FuncDecl->getLinkage() == GlobalValue::InternalLinkage);
Karl Schimpf98ed4462015-08-14 13:08:42 -07001252 CurrentNode = installNextBasicBlock();
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08001253 Func->setEntryNode(CurrentNode);
1254 for (Ice::Type ArgType : Signature.getArgList()) {
1255 Func->addArg(getNextInstVar(ArgType));
1256 }
Karl Schimpfd6064a12014-08-27 15:34:58 -07001257 }
Jim Stichnoth8e928382015-02-02 17:03:08 -08001258 bool ParserResult = ParseThisBlock();
1259
1260 // Temporarily end per-function timing, which will be resumed by
1261 // the translator function. This is because translation may be
1262 // done asynchronously in a separate thread.
1263 if (TimeThisFunction)
1264 getTranslator().getContext()->popTimer(TimerID, StackID);
1265
1266 Ice::Cfg::setCurrentCfg(nullptr);
1267 // Note: Once any errors have been found, we turn off all
1268 // translation of all remaining functions. This allows successive
1269 // parsing errors to be reported, without adding extra checks to
1270 // the translator for such parsing errors.
Jim Stichnothbbca7542015-02-11 16:08:31 -08001271 if (Context->getNumErrors() == 0 && Func) {
Jim Stichnoth8e928382015-02-02 17:03:08 -08001272 getTranslator().translateFcn(std::move(Func));
1273 // The translator now has ownership of Func.
1274 } else {
1275 Func.reset();
1276 }
1277
1278 return ParserResult;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001279 }
1280
Jim Stichnothe587d942015-06-22 15:49:04 -07001281 ~FunctionParser() final = default;
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08001282
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001283 const char *getBlockName() const override { return "function"; }
1284
Jim Stichnoth8e928382015-02-02 17:03:08 -08001285 Ice::Cfg *getFunc() const { return Func.get(); }
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001286
Karl Schimpf74cd8832015-06-23 11:05:01 -07001287 size_t getNumGlobalIDs() const { return CachedNumGlobalValueIDs; }
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001288
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08001289 void setNextLocalInstIndex(Ice::Operand *Op) {
1290 setOperand(NextLocalInstIndex++, Op);
1291 }
Karl Schimpfd6064a12014-08-27 15:34:58 -07001292
Karl Schimpff12355e2014-09-08 13:41:09 -07001293 // Set the next constant ID to the given constant C.
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08001294 void setNextConstantID(Ice::Constant *C) { setNextLocalInstIndex(C); }
Karl Schimpff12355e2014-09-08 13:41:09 -07001295
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001296 // Returns the value referenced by the given value Index.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001297 Ice::Operand *getOperand(NaClBcIndexSize_t Index) {
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001298 if (Index < CachedNumGlobalValueIDs) {
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -08001299 return Context->getGlobalConstantByID(Index);
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001300 }
Karl Schimpf74cd8832015-06-23 11:05:01 -07001301 NaClBcIndexSize_t LocalIndex = Index - CachedNumGlobalValueIDs;
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001302 Ice::Operand *Op = LocalOperands[LocalIndex];
1303 if (Op == nullptr) {
1304 if (isIRGenerationDisabled())
1305 return nullptr;
1306 std::string Buffer;
1307 raw_string_ostream StrBuf(Buffer);
1308 StrBuf << "Value index " << Index << " not defined!";
Karl Schimpf22ed4eb2015-03-04 12:17:20 -08001309 Fatal(StrBuf.str());
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001310 }
1311 return Op;
1312 }
1313
Karl Schimpfd6064a12014-08-27 15:34:58 -07001314private:
Karl Schimpf58455872014-11-03 11:29:39 -08001315 Ice::TimerMarker Timer;
Karl Schimpf98ed4462015-08-14 13:08:42 -07001316 // The number of words in the bitstream defining the function block.
1317 uint64_t NumBytesDefiningFunction = 0;
Karl Schimpf7a993272015-08-17 12:43:29 -07001318 // Maximum number of records that can appear in the function block, based on
1319 // the number of bytes defining the function block.
1320 uint64_t MaxRecordsInBlock = 0;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001321 // The corresponding ICE function defined by the function block.
Jim Stichnoth8e928382015-02-02 17:03:08 -08001322 std::unique_ptr<Ice::Cfg> Func;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001323 // The index to the current basic block being built.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001324 NaClBcIndexSize_t CurrentBbIndex = 0;
Karl Schimpf98ed4462015-08-14 13:08:42 -07001325 // The number of basic blocks declared for the function block.
1326 NaClBcIndexSize_t DeclaredNumberBbs = 0;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001327 // The basic block being built.
Jim Stichnotheafb56c2015-06-22 10:35:22 -07001328 Ice::CfgNode *CurrentNode = nullptr;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001329 // The ID for the function.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001330 NaClBcIndexSize_t FcnId;
Karl Schimpf9d98d792014-10-13 15:01:08 -07001331 // The corresponding function declaration.
1332 Ice::FunctionDeclaration *FuncDecl;
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001333 // Holds the dividing point between local and global absolute value indices.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001334 size_t CachedNumGlobalValueIDs;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001335 // Holds operands local to the function block, based on indices
1336 // defined in the bitcode file.
Karl Schimpf209318a2015-08-20 13:24:02 -07001337 Ice::OperandList LocalOperands;
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001338 // Holds the index within LocalOperands corresponding to the next
1339 // instruction that generates a value.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001340 NaClBcIndexSize_t NextLocalInstIndex;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001341 // True if the last processed instruction was a terminating
1342 // instruction.
Jim Stichnotheafb56c2015-06-22 10:35:22 -07001343 bool InstIsTerminating = false;
Karl Schimpf742d72d2014-09-09 11:40:09 -07001344 // Upper limit of alignment power allowed by LLVM
Karl Schimpff875d452014-12-09 13:50:07 -08001345 static const uint32_t AlignPowerLimit = 29;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001346
Karl Schimpf41689df2014-09-10 14:36:07 -07001347 // Extracts the corresponding Alignment to use, given the AlignPower
Karl Schimpfaf238b22015-01-20 12:19:15 -08001348 // (i.e. 2**(AlignPower-1), or 0 if AlignPower == 0). InstName is the
Karl Schimpf41689df2014-09-10 14:36:07 -07001349 // name of the instruction the alignment appears in.
Karl Schimpff875d452014-12-09 13:50:07 -08001350 void extractAlignment(const char *InstName, uint32_t AlignPower,
1351 uint32_t &Alignment) {
Karl Schimpfaf238b22015-01-20 12:19:15 -08001352 if (AlignPower <= AlignPowerLimit + 1) {
Karl Schimpff875d452014-12-09 13:50:07 -08001353 Alignment = (1 << AlignPower) >> 1;
Karl Schimpf41689df2014-09-10 14:36:07 -07001354 return;
1355 }
1356 std::string Buffer;
1357 raw_string_ostream StrBuf(Buffer);
1358 StrBuf << InstName << " alignment greater than 2**" << AlignPowerLimit
Karl Schimpfaf238b22015-01-20 12:19:15 -08001359 << ". Found: 2**" << (AlignPower - 1);
Karl Schimpf41689df2014-09-10 14:36:07 -07001360 Error(StrBuf.str());
1361 // Error recover with value that is always acceptable.
1362 Alignment = 1;
1363 }
1364
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07001365 bool ParseBlock(unsigned BlockID) override;
Karl Schimpff12355e2014-09-08 13:41:09 -07001366
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07001367 void ProcessRecord() override;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001368
Karl Schimpf98ed4462015-08-14 13:08:42 -07001369 void EnterBlock(unsigned NumWords) final {
1370 // Note: Bitstream defines words as 32-bit values.
1371 NumBytesDefiningFunction = NumWords * sizeof(uint32_t);
Karl Schimpf7a993272015-08-17 12:43:29 -07001372 // We know that all records are minimally defined by a two-bit abreviation.
1373 MaxRecordsInBlock = NumBytesDefiningFunction * (CHAR_BIT >> 1);
Karl Schimpf98ed4462015-08-14 13:08:42 -07001374 }
1375
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07001376 void ExitBlock() override;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001377
Karl Schimpf98ed4462015-08-14 13:08:42 -07001378 // Creates and appends a new basic block to the list of basic blocks.
1379 Ice::CfgNode *installNextBasicBlock() {
1380 assert(!isIRGenerationDisabled());
1381 Ice::CfgNode *Node = Func->makeNode();
1382 return Node;
1383 }
1384
1385 // Returns the Index-th basic block in the list of basic blocks.
1386 Ice::CfgNode *getBasicBlock(NaClBcIndexSize_t Index) {
1387 assert(!isIRGenerationDisabled());
1388 if (Index >= Func->getNumNodes()) {
1389 std::string Buffer;
1390 raw_string_ostream StrBuf(Buffer);
1391 StrBuf << "Reference to basic block " << Index
1392 << " not found. Must be less than " << Func->getNumNodes();
1393 Error(StrBuf.str());
1394 Index = 0;
1395 }
1396 return Func->getNodes()[Index];
1397 }
1398
Karl Schimpfc836acb2014-09-05 08:32:47 -07001399 // Returns the Index-th basic block in the list of basic blocks.
1400 // Assumes Index corresponds to a branch instruction. Hence, if
1401 // the branch references the entry block, it also generates a
1402 // corresponding error.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001403 Ice::CfgNode *getBranchBasicBlock(NaClBcIndexSize_t Index) {
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08001404 assert(!isIRGenerationDisabled());
Karl Schimpfc836acb2014-09-05 08:32:47 -07001405 if (Index == 0) {
1406 Error("Branch to entry block not allowed");
Karl Schimpfc836acb2014-09-05 08:32:47 -07001407 }
Karl Schimpf47661562014-09-11 14:42:49 -07001408 return getBasicBlock(Index);
Karl Schimpfc836acb2014-09-05 08:32:47 -07001409 }
1410
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001411 // Generate an instruction variable with type Ty.
1412 Ice::Variable *createInstVar(Ice::Type Ty) {
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08001413 assert(!isIRGenerationDisabled());
Karl Schimpf47661562014-09-11 14:42:49 -07001414 if (Ty == Ice::IceType_void) {
1415 Error("Can't define instruction value using type void");
1416 // Recover since we can't throw an exception.
1417 Ty = Ice::IceType_i32;
1418 }
Jim Stichnoth144cdce2014-09-22 16:02:59 -07001419 return Func->makeVariable(Ty);
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001420 }
1421
1422 // Generates the next available local variable using the given type.
1423 Ice::Variable *getNextInstVar(Ice::Type Ty) {
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08001424 assert(!isIRGenerationDisabled());
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001425 assert(NextLocalInstIndex >= CachedNumGlobalValueIDs);
1426 // Before creating one, see if a forwardtyperef has already defined it.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001427 NaClBcIndexSize_t LocalIndex = NextLocalInstIndex - CachedNumGlobalValueIDs;
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001428 if (LocalIndex < LocalOperands.size()) {
1429 Ice::Operand *Op = LocalOperands[LocalIndex];
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001430 if (Op != nullptr) {
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001431 if (Ice::Variable *Var = dyn_cast<Ice::Variable>(Op)) {
1432 if (Var->getType() == Ty) {
1433 ++NextLocalInstIndex;
1434 return Var;
1435 }
1436 }
1437 std::string Buffer;
1438 raw_string_ostream StrBuf(Buffer);
1439 StrBuf << "Illegal forward referenced instruction ("
1440 << NextLocalInstIndex << "): " << *Op;
1441 Error(StrBuf.str());
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001442 ++NextLocalInstIndex;
1443 return createInstVar(Ty);
1444 }
1445 }
1446 Ice::Variable *Var = createInstVar(Ty);
1447 setOperand(NextLocalInstIndex++, Var);
Karl Schimpfd6064a12014-08-27 15:34:58 -07001448 return Var;
1449 }
1450
Karl Schimpf47661562014-09-11 14:42:49 -07001451 // Converts a relative index (wrt to BaseIndex) to an absolute value
1452 // index.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001453 NaClBcIndexSize_t convertRelativeToAbsIndex(NaClRelBcIndexSize_t Id,
1454 NaClRelBcIndexSize_t BaseIndex) {
Karl Schimpf47661562014-09-11 14:42:49 -07001455 if (BaseIndex < Id) {
Karl Schimpfd6064a12014-08-27 15:34:58 -07001456 std::string Buffer;
1457 raw_string_ostream StrBuf(Buffer);
1458 StrBuf << "Invalid relative value id: " << Id
Karl Schimpf47661562014-09-11 14:42:49 -07001459 << " (must be <= " << BaseIndex << ")";
Karl Schimpfd6064a12014-08-27 15:34:58 -07001460 Error(StrBuf.str());
Karl Schimpfd6064a12014-08-27 15:34:58 -07001461 return 0;
1462 }
Karl Schimpf47661562014-09-11 14:42:49 -07001463 return BaseIndex - Id;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001464 }
1465
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001466 // Sets element Index (in the local operands list) to Op.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001467 void setOperand(NaClBcIndexSize_t Index, Ice::Operand *Op) {
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08001468 assert(Op || isIRGenerationDisabled());
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001469 // Check if simple push works.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001470 NaClBcIndexSize_t LocalIndex = Index - CachedNumGlobalValueIDs;
Karl Schimpf7a993272015-08-17 12:43:29 -07001471 if (LocalIndex == LocalOperands.size()) {
1472 LocalOperands.push_back(Op);
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001473 return;
1474 }
1475
Karl Schimpf7a993272015-08-17 12:43:29 -07001476 // Must be forward reference, expand vector to accommodate.
1477 if (LocalIndex >= LocalOperands.size()) {
1478 if (LocalIndex > MaxRecordsInBlock) {
1479 std::string Buffer;
1480 raw_string_ostream StrBuf(Buffer);
1481 StrBuf << "Forward reference @" << Index << " too big. Have "
1482 << CachedNumGlobalValueIDs << " globals and function contains "
1483 << NumBytesDefiningFunction << " bytes";
1484 Fatal(StrBuf.str());
1485 // Recover by using index one beyond the maximal allowed.
1486 LocalIndex = MaxRecordsInBlock;
1487 }
1488 LocalOperands.resize(LocalIndex + 1);
1489 }
1490
1491 // If element not defined, set it.
1492 Ice::Operand *OldOp = LocalOperands[LocalIndex];
1493 if (OldOp == nullptr) {
1494 LocalOperands[LocalIndex] = Op;
1495 return;
1496 }
1497
1498 // See if forward reference matches.
1499 if (OldOp == Op)
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001500 return;
1501
1502 // Error has occurred.
1503 std::string Buffer;
1504 raw_string_ostream StrBuf(Buffer);
Karl Schimpfd1a971a2014-09-17 15:38:17 -07001505 StrBuf << "Multiple definitions for index " << Index << ": " << *Op
Karl Schimpf7a993272015-08-17 12:43:29 -07001506 << " and " << *OldOp;
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001507 Error(StrBuf.str());
Karl Schimpf7a993272015-08-17 12:43:29 -07001508 LocalOperands[LocalIndex] = Op;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001509 }
1510
Karl Schimpf47661562014-09-11 14:42:49 -07001511 // Returns the relative operand (wrt to BaseIndex) referenced by
1512 // the given value Index.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001513 Ice::Operand *getRelativeOperand(NaClBcIndexSize_t Index,
1514 NaClBcIndexSize_t BaseIndex) {
Karl Schimpf47661562014-09-11 14:42:49 -07001515 return getOperand(convertRelativeToAbsIndex(Index, BaseIndex));
1516 }
1517
1518 // Returns the absolute index of the next value generating instruction.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001519 NaClBcIndexSize_t getNextInstIndex() const { return NextLocalInstIndex; }
Karl Schimpf71ba8222014-09-03 09:46:24 -07001520
Karl Schimpfd6064a12014-08-27 15:34:58 -07001521 // Generates type error message for binary operator Op
1522 // operating on Type OpTy.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001523 void reportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy);
Karl Schimpfd6064a12014-08-27 15:34:58 -07001524
1525 // Validates if integer logical Op, for type OpTy, is valid.
1526 // Returns true if valid. Otherwise generates error message and
1527 // returns false.
1528 bool isValidIntegerLogicalOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
1529 if (Ice::isIntegerType(OpTy))
1530 return true;
Karl Schimpf74cd8832015-06-23 11:05:01 -07001531 reportInvalidBinaryOp(Op, OpTy);
Karl Schimpfd6064a12014-08-27 15:34:58 -07001532 return false;
1533 }
1534
1535 // Validates if integer (or vector of integers) arithmetic Op, for type
1536 // OpTy, is valid. Returns true if valid. Otherwise generates
1537 // error message and returns false.
1538 bool isValidIntegerArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
1539 if (Ice::isIntegerArithmeticType(OpTy))
1540 return true;
Karl Schimpf74cd8832015-06-23 11:05:01 -07001541 reportInvalidBinaryOp(Op, OpTy);
Karl Schimpfd6064a12014-08-27 15:34:58 -07001542 return false;
1543 }
1544
1545 // Checks if floating arithmetic Op, for type OpTy, is valid.
Karl Schimpf41689df2014-09-10 14:36:07 -07001546 // Returns true if valid. Otherwise generates an error message and
1547 // returns false;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001548 bool isValidFloatingArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
1549 if (Ice::isFloatingType(OpTy))
1550 return true;
Karl Schimpf74cd8832015-06-23 11:05:01 -07001551 reportInvalidBinaryOp(Op, OpTy);
Karl Schimpfd6064a12014-08-27 15:34:58 -07001552 return false;
1553 }
1554
Karl Schimpf41689df2014-09-10 14:36:07 -07001555 // Checks if the type of operand Op is the valid pointer type, for
1556 // the given InstructionName. Returns true if valid. Otherwise
1557 // generates an error message and returns false.
1558 bool isValidPointerType(Ice::Operand *Op, const char *InstructionName) {
Karl Schimpf4019f082014-12-15 13:45:00 -08001559 Ice::Type PtrType = Ice::getPointerType();
Karl Schimpf41689df2014-09-10 14:36:07 -07001560 if (Op->getType() == PtrType)
1561 return true;
1562 std::string Buffer;
1563 raw_string_ostream StrBuf(Buffer);
1564 StrBuf << InstructionName << " address not " << PtrType
Karl Schimpf97501832014-09-16 13:35:32 -07001565 << ". Found: " << *Op;
Karl Schimpf41689df2014-09-10 14:36:07 -07001566 Error(StrBuf.str());
1567 return false;
1568 }
1569
1570 // Checks if loading/storing a value of type Ty is allowed.
1571 // Returns true if Valid. Otherwise generates an error message and
1572 // returns false.
1573 bool isValidLoadStoreType(Ice::Type Ty, const char *InstructionName) {
1574 if (isLoadStoreType(Ty))
1575 return true;
1576 std::string Buffer;
1577 raw_string_ostream StrBuf(Buffer);
1578 StrBuf << InstructionName << " type not allowed: " << Ty << "*";
1579 Error(StrBuf.str());
1580 return false;
1581 }
1582
1583 // Checks if loading/storing a value of type Ty is allowed for
1584 // the given Alignment. Otherwise generates an error message and
1585 // returns false.
Karl Schimpff875d452014-12-09 13:50:07 -08001586 bool isValidLoadStoreAlignment(size_t Alignment, Ice::Type Ty,
Karl Schimpf41689df2014-09-10 14:36:07 -07001587 const char *InstructionName) {
1588 if (!isValidLoadStoreType(Ty, InstructionName))
1589 return false;
Karl Schimpff875d452014-12-09 13:50:07 -08001590 if (isAllowedAlignment(Alignment, Ty))
Karl Schimpf41689df2014-09-10 14:36:07 -07001591 return true;
1592 std::string Buffer;
1593 raw_string_ostream StrBuf(Buffer);
1594 StrBuf << InstructionName << " " << Ty << "*: not allowed for alignment "
1595 << Alignment;
1596 Error(StrBuf.str());
1597 return false;
1598 }
1599
Karl Schimpff875d452014-12-09 13:50:07 -08001600 // Defines if the given alignment is valid for the given type. Simplified
1601 // version of PNaClABIProps::isAllowedAlignment, based on API's offered
1602 // for Ice::Type.
1603 bool isAllowedAlignment(size_t Alignment, Ice::Type Ty) const {
1604 return Alignment == typeAlignInBytes(Ty) ||
1605 (Alignment == 1 && !isVectorType(Ty));
1606 }
1607
Karl Schimpfaff9fa22014-10-29 14:32:07 -07001608 // Types of errors that can occur for insertelement and extractelement
1609 // instructions.
1610 enum VectorIndexCheckValue {
1611 VectorIndexNotVector,
1612 VectorIndexNotConstant,
1613 VectorIndexNotInRange,
1614 VectorIndexNotI32,
1615 VectorIndexValid
1616 };
1617
1618 void dumpVectorIndexCheckValue(raw_ostream &Stream,
1619 VectorIndexCheckValue Value) const {
Jim Stichnoth20b71f52015-06-24 15:52:24 -07001620 if (!Ice::BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -08001621 return;
Karl Schimpfaff9fa22014-10-29 14:32:07 -07001622 switch (Value) {
Karl Schimpfaff9fa22014-10-29 14:32:07 -07001623 case VectorIndexNotVector:
1624 Stream << "Vector index on non vector";
1625 break;
1626 case VectorIndexNotConstant:
1627 Stream << "Vector index not integer constant";
1628 break;
1629 case VectorIndexNotInRange:
1630 Stream << "Vector index not in range of vector";
1631 break;
1632 case VectorIndexNotI32:
1633 Stream << "Vector index not of type " << Ice::IceType_i32;
1634 break;
1635 case VectorIndexValid:
1636 Stream << "Valid vector index";
1637 break;
1638 }
1639 }
1640
1641 // Returns whether the given vector index (for insertelement and
1642 // extractelement instructions) is valid.
1643 VectorIndexCheckValue validateVectorIndex(const Ice::Operand *Vec,
1644 const Ice::Operand *Index) const {
1645 Ice::Type VecType = Vec->getType();
1646 if (!Ice::isVectorType(VecType))
1647 return VectorIndexNotVector;
1648 const auto *C = dyn_cast<Ice::ConstantInteger32>(Index);
1649 if (C == nullptr)
1650 return VectorIndexNotConstant;
Jim Stichnothd2cb4362014-11-20 11:24:42 -08001651 if (static_cast<size_t>(C->getValue()) >= typeNumElements(VecType))
Karl Schimpfaff9fa22014-10-29 14:32:07 -07001652 return VectorIndexNotInRange;
1653 if (Index->getType() != Ice::IceType_i32)
1654 return VectorIndexNotI32;
1655 return VectorIndexValid;
1656 }
1657
Karl Schimpfd6064a12014-08-27 15:34:58 -07001658 // Takes the PNaCl bitcode binary operator Opcode, and the opcode
1659 // type Ty, and sets Op to the corresponding ICE binary
1660 // opcode. Returns true if able to convert, false otherwise.
1661 bool convertBinopOpcode(unsigned Opcode, Ice::Type Ty,
1662 Ice::InstArithmetic::OpKind &Op) {
Karl Schimpf9bb188d2014-12-10 12:54:34 -08001663 switch (Opcode) {
Karl Schimpfd6064a12014-08-27 15:34:58 -07001664 default: {
Karl Schimpf9bb188d2014-12-10 12:54:34 -08001665 std::string Buffer;
1666 raw_string_ostream StrBuf(Buffer);
1667 StrBuf << "Binary opcode " << Opcode << "not understood for type " << Ty;
1668 Error(StrBuf.str());
Karl Schimpfd6064a12014-08-27 15:34:58 -07001669 Op = Ice::InstArithmetic::Add;
1670 return false;
1671 }
Karl Schimpf9bb188d2014-12-10 12:54:34 -08001672 case naclbitc::BINOP_ADD:
1673 if (Ice::isIntegerType(Ty)) {
1674 Op = Ice::InstArithmetic::Add;
1675 return isValidIntegerArithOp(Op, Ty);
1676 } else {
1677 Op = Ice::InstArithmetic::Fadd;
1678 return isValidFloatingArithOp(Op, Ty);
1679 }
1680 case naclbitc::BINOP_SUB:
1681 if (Ice::isIntegerType(Ty)) {
1682 Op = Ice::InstArithmetic::Sub;
1683 return isValidIntegerArithOp(Op, Ty);
1684 } else {
1685 Op = Ice::InstArithmetic::Fsub;
1686 return isValidFloatingArithOp(Op, Ty);
1687 }
1688 case naclbitc::BINOP_MUL:
1689 if (Ice::isIntegerType(Ty)) {
1690 Op = Ice::InstArithmetic::Mul;
1691 return isValidIntegerArithOp(Op, Ty);
1692 } else {
1693 Op = Ice::InstArithmetic::Fmul;
1694 return isValidFloatingArithOp(Op, Ty);
1695 }
1696 case naclbitc::BINOP_UDIV:
Karl Schimpfd6064a12014-08-27 15:34:58 -07001697 Op = Ice::InstArithmetic::Udiv;
1698 return isValidIntegerArithOp(Op, Ty);
Karl Schimpf9bb188d2014-12-10 12:54:34 -08001699 case naclbitc::BINOP_SDIV:
1700 if (Ice::isIntegerType(Ty)) {
1701 Op = Ice::InstArithmetic::Sdiv;
1702 return isValidIntegerArithOp(Op, Ty);
1703 } else {
1704 Op = Ice::InstArithmetic::Fdiv;
1705 return isValidFloatingArithOp(Op, Ty);
1706 }
1707 case naclbitc::BINOP_UREM:
Karl Schimpfd6064a12014-08-27 15:34:58 -07001708 Op = Ice::InstArithmetic::Urem;
1709 return isValidIntegerArithOp(Op, Ty);
Karl Schimpf9bb188d2014-12-10 12:54:34 -08001710 case naclbitc::BINOP_SREM:
1711 if (Ice::isIntegerType(Ty)) {
1712 Op = Ice::InstArithmetic::Srem;
1713 return isValidIntegerArithOp(Op, Ty);
1714 } else {
1715 Op = Ice::InstArithmetic::Frem;
1716 return isValidFloatingArithOp(Op, Ty);
1717 }
1718 case naclbitc::BINOP_SHL:
Karl Schimpfd6064a12014-08-27 15:34:58 -07001719 Op = Ice::InstArithmetic::Shl;
1720 return isValidIntegerArithOp(Op, Ty);
Karl Schimpf9bb188d2014-12-10 12:54:34 -08001721 case naclbitc::BINOP_LSHR:
Karl Schimpfd6064a12014-08-27 15:34:58 -07001722 Op = Ice::InstArithmetic::Lshr;
1723 return isValidIntegerArithOp(Op, Ty);
Karl Schimpf9bb188d2014-12-10 12:54:34 -08001724 case naclbitc::BINOP_ASHR:
Karl Schimpfd6064a12014-08-27 15:34:58 -07001725 Op = Ice::InstArithmetic::Ashr;
1726 return isValidIntegerArithOp(Op, Ty);
Karl Schimpf9bb188d2014-12-10 12:54:34 -08001727 case naclbitc::BINOP_AND:
Karl Schimpfd6064a12014-08-27 15:34:58 -07001728 Op = Ice::InstArithmetic::And;
1729 return isValidIntegerLogicalOp(Op, Ty);
Karl Schimpf9bb188d2014-12-10 12:54:34 -08001730 case naclbitc::BINOP_OR:
Karl Schimpfd6064a12014-08-27 15:34:58 -07001731 Op = Ice::InstArithmetic::Or;
1732 return isValidIntegerLogicalOp(Op, Ty);
Karl Schimpf9bb188d2014-12-10 12:54:34 -08001733 case naclbitc::BINOP_XOR:
Karl Schimpfd6064a12014-08-27 15:34:58 -07001734 Op = Ice::InstArithmetic::Xor;
1735 return isValidIntegerLogicalOp(Op, Ty);
1736 }
1737 }
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001738
Karl Schimpfbf170372014-12-15 10:16:31 -08001739 /// Simplifies out vector types from Type1 and Type2, if both are vectors
1740 /// of the same size. Returns true iff both are vectors of the same size,
1741 /// or are both scalar types.
1742 static bool simplifyOutCommonVectorType(Ice::Type &Type1, Ice::Type &Type2) {
1743 bool IsType1Vector = isVectorType(Type1);
1744 bool IsType2Vector = isVectorType(Type2);
1745 if (IsType1Vector != IsType2Vector)
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001746 return false;
Karl Schimpfbf170372014-12-15 10:16:31 -08001747 if (!IsType1Vector)
1748 return true;
1749 if (typeNumElements(Type1) != typeNumElements(Type2))
1750 return false;
1751 Type1 = typeElementType(Type1);
1752 Type2 = typeElementType(Type2);
1753 return true;
1754 }
1755
1756 /// Returns true iff an integer truncation from SourceType to TargetType is
1757 /// valid.
1758 static bool isIntTruncCastValid(Ice::Type SourceType, Ice::Type TargetType) {
Jim Stichnothdd842db2015-01-27 12:53:53 -08001759 return Ice::isIntegerType(SourceType) && Ice::isIntegerType(TargetType) &&
1760 simplifyOutCommonVectorType(SourceType, TargetType) &&
1761 getScalarIntBitWidth(SourceType) > getScalarIntBitWidth(TargetType);
Karl Schimpfbf170372014-12-15 10:16:31 -08001762 }
1763
1764 /// Returns true iff a floating type truncation from SourceType to TargetType
1765 /// is valid.
1766 static bool isFloatTruncCastValid(Ice::Type SourceType,
1767 Ice::Type TargetType) {
Jim Stichnothdd842db2015-01-27 12:53:53 -08001768 return simplifyOutCommonVectorType(SourceType, TargetType) &&
1769 SourceType == Ice::IceType_f64 && TargetType == Ice::IceType_f32;
Karl Schimpfbf170372014-12-15 10:16:31 -08001770 }
1771
1772 /// Returns true iff an integer extension from SourceType to TargetType is
1773 /// valid.
1774 static bool isIntExtCastValid(Ice::Type SourceType, Ice::Type TargetType) {
1775 return isIntTruncCastValid(TargetType, SourceType);
1776 }
1777
1778 /// Returns true iff a floating type extension from SourceType to TargetType
1779 /// is valid.
1780 static bool isFloatExtCastValid(Ice::Type SourceType, Ice::Type TargetType) {
1781 return isFloatTruncCastValid(TargetType, SourceType);
1782 }
1783
1784 /// Returns true iff a cast from floating type SourceType to integer
1785 /// type TargetType is valid.
1786 static bool isFloatToIntCastValid(Ice::Type SourceType,
1787 Ice::Type TargetType) {
1788 if (!(Ice::isFloatingType(SourceType) && Ice::isIntegerType(TargetType)))
1789 return false;
1790 bool IsSourceVector = isVectorType(SourceType);
1791 bool IsTargetVector = isVectorType(TargetType);
1792 if (IsSourceVector != IsTargetVector)
1793 return false;
1794 if (IsSourceVector) {
1795 return typeNumElements(SourceType) == typeNumElements(TargetType);
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001796 }
1797 return true;
1798 }
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07001799
Karl Schimpfbf170372014-12-15 10:16:31 -08001800 /// Returns true iff a cast from integer type SourceType to floating
1801 /// type TargetType is valid.
1802 static bool isIntToFloatCastValid(Ice::Type SourceType,
1803 Ice::Type TargetType) {
1804 return isFloatToIntCastValid(TargetType, SourceType);
1805 }
1806
1807 /// Returns the number of bits used to model type Ty when defining the
1808 /// bitcast instruction.
1809 static Ice::SizeT bitcastSizeInBits(Ice::Type Ty) {
1810 if (Ice::isVectorType(Ty))
1811 return Ice::typeNumElements(Ty) *
1812 bitcastSizeInBits(Ice::typeElementType(Ty));
1813 if (Ty == Ice::IceType_i1)
1814 return 1;
1815 return Ice::typeWidthInBytes(Ty) * CHAR_BIT;
1816 }
1817
1818 /// Returns true iff a bitcast from SourceType to TargetType is allowed.
1819 static bool isBitcastValid(Ice::Type SourceType, Ice::Type TargetType) {
1820 return bitcastSizeInBits(SourceType) == bitcastSizeInBits(TargetType);
1821 }
1822
1823 /// Returns true iff the NaCl bitcode Opcode is a valid cast opcode
1824 /// for converting SourceType to TargetType. Updates CastKind to the
1825 /// corresponding instruction cast opcode. Also generates an error
1826 /// message when this function returns false.
1827 bool convertCastOpToIceOp(uint64_t Opcode, Ice::Type SourceType,
1828 Ice::Type TargetType,
1829 Ice::InstCast::OpKind &CastKind) {
1830 bool Result;
1831 switch (Opcode) {
1832 default: {
1833 std::string Buffer;
1834 raw_string_ostream StrBuf(Buffer);
1835 StrBuf << "Cast opcode " << Opcode << " not understood.\n";
1836 Error(StrBuf.str());
Karl Schimpfbf170372014-12-15 10:16:31 -08001837 CastKind = Ice::InstCast::Bitcast;
1838 return false;
1839 }
1840 case naclbitc::CAST_TRUNC:
1841 CastKind = Ice::InstCast::Trunc;
1842 Result = isIntTruncCastValid(SourceType, TargetType);
1843 break;
1844 case naclbitc::CAST_ZEXT:
1845 CastKind = Ice::InstCast::Zext;
1846 Result = isIntExtCastValid(SourceType, TargetType);
1847 break;
1848 case naclbitc::CAST_SEXT:
1849 CastKind = Ice::InstCast::Sext;
1850 Result = isIntExtCastValid(SourceType, TargetType);
1851 break;
1852 case naclbitc::CAST_FPTOUI:
1853 CastKind = Ice::InstCast::Fptoui;
1854 Result = isFloatToIntCastValid(SourceType, TargetType);
1855 break;
1856 case naclbitc::CAST_FPTOSI:
1857 CastKind = Ice::InstCast::Fptosi;
1858 Result = isFloatToIntCastValid(SourceType, TargetType);
1859 break;
1860 case naclbitc::CAST_UITOFP:
1861 CastKind = Ice::InstCast::Uitofp;
1862 Result = isIntToFloatCastValid(SourceType, TargetType);
1863 break;
1864 case naclbitc::CAST_SITOFP:
1865 CastKind = Ice::InstCast::Sitofp;
1866 Result = isIntToFloatCastValid(SourceType, TargetType);
1867 break;
1868 case naclbitc::CAST_FPTRUNC:
1869 CastKind = Ice::InstCast::Fptrunc;
1870 Result = isFloatTruncCastValid(SourceType, TargetType);
1871 break;
1872 case naclbitc::CAST_FPEXT:
1873 CastKind = Ice::InstCast::Fpext;
1874 Result = isFloatExtCastValid(SourceType, TargetType);
1875 break;
1876 case naclbitc::CAST_BITCAST:
1877 CastKind = Ice::InstCast::Bitcast;
1878 Result = isBitcastValid(SourceType, TargetType);
1879 break;
1880 }
1881 if (!Result) {
1882 std::string Buffer;
1883 raw_string_ostream StrBuf(Buffer);
1884 StrBuf << "Illegal cast: " << Ice::InstCast::getCastName(CastKind) << " "
1885 << SourceType << " to " << TargetType;
1886 Error(StrBuf.str());
1887 }
1888 return Result;
1889 }
1890
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07001891 // Converts PNaCl bitcode Icmp operator to corresponding ICE op.
1892 // Returns true if able to convert, false otherwise.
1893 bool convertNaClBitcICmpOpToIce(uint64_t Op,
1894 Ice::InstIcmp::ICond &Cond) const {
1895 switch (Op) {
1896 case naclbitc::ICMP_EQ:
1897 Cond = Ice::InstIcmp::Eq;
1898 return true;
1899 case naclbitc::ICMP_NE:
1900 Cond = Ice::InstIcmp::Ne;
1901 return true;
1902 case naclbitc::ICMP_UGT:
1903 Cond = Ice::InstIcmp::Ugt;
1904 return true;
1905 case naclbitc::ICMP_UGE:
1906 Cond = Ice::InstIcmp::Uge;
1907 return true;
1908 case naclbitc::ICMP_ULT:
1909 Cond = Ice::InstIcmp::Ult;
1910 return true;
1911 case naclbitc::ICMP_ULE:
1912 Cond = Ice::InstIcmp::Ule;
1913 return true;
1914 case naclbitc::ICMP_SGT:
1915 Cond = Ice::InstIcmp::Sgt;
1916 return true;
1917 case naclbitc::ICMP_SGE:
1918 Cond = Ice::InstIcmp::Sge;
1919 return true;
1920 case naclbitc::ICMP_SLT:
1921 Cond = Ice::InstIcmp::Slt;
1922 return true;
1923 case naclbitc::ICMP_SLE:
1924 Cond = Ice::InstIcmp::Sle;
1925 return true;
1926 default:
Jim Stichnothdddaf9c2014-12-04 14:09:21 -08001927 // Make sure Cond is always initialized.
1928 Cond = static_cast<Ice::InstIcmp::ICond>(0);
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07001929 return false;
1930 }
1931 }
1932
1933 // Converts PNaCl bitcode Fcmp operator to corresponding ICE op.
1934 // Returns true if able to convert, false otherwise.
1935 bool convertNaClBitcFCompOpToIce(uint64_t Op,
1936 Ice::InstFcmp::FCond &Cond) const {
1937 switch (Op) {
1938 case naclbitc::FCMP_FALSE:
1939 Cond = Ice::InstFcmp::False;
1940 return true;
1941 case naclbitc::FCMP_OEQ:
1942 Cond = Ice::InstFcmp::Oeq;
1943 return true;
1944 case naclbitc::FCMP_OGT:
1945 Cond = Ice::InstFcmp::Ogt;
1946 return true;
1947 case naclbitc::FCMP_OGE:
1948 Cond = Ice::InstFcmp::Oge;
1949 return true;
1950 case naclbitc::FCMP_OLT:
1951 Cond = Ice::InstFcmp::Olt;
1952 return true;
1953 case naclbitc::FCMP_OLE:
1954 Cond = Ice::InstFcmp::Ole;
1955 return true;
1956 case naclbitc::FCMP_ONE:
1957 Cond = Ice::InstFcmp::One;
1958 return true;
1959 case naclbitc::FCMP_ORD:
1960 Cond = Ice::InstFcmp::Ord;
1961 return true;
1962 case naclbitc::FCMP_UNO:
1963 Cond = Ice::InstFcmp::Uno;
1964 return true;
1965 case naclbitc::FCMP_UEQ:
1966 Cond = Ice::InstFcmp::Ueq;
1967 return true;
1968 case naclbitc::FCMP_UGT:
1969 Cond = Ice::InstFcmp::Ugt;
1970 return true;
1971 case naclbitc::FCMP_UGE:
1972 Cond = Ice::InstFcmp::Uge;
1973 return true;
1974 case naclbitc::FCMP_ULT:
1975 Cond = Ice::InstFcmp::Ult;
1976 return true;
1977 case naclbitc::FCMP_ULE:
1978 Cond = Ice::InstFcmp::Ule;
1979 return true;
1980 case naclbitc::FCMP_UNE:
1981 Cond = Ice::InstFcmp::Une;
1982 return true;
1983 case naclbitc::FCMP_TRUE:
1984 Cond = Ice::InstFcmp::True;
1985 return true;
1986 default:
Jim Stichnothdddaf9c2014-12-04 14:09:21 -08001987 // Make sure Cond is always initialized.
1988 Cond = static_cast<Ice::InstFcmp::FCond>(0);
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07001989 return false;
1990 }
1991 }
Karl Schimpfaff9fa22014-10-29 14:32:07 -07001992
1993 // Creates an error instruction, generating a value of type Ty, and
1994 // adds a placeholder so that instruction indices line up.
1995 // Some instructions, such as a call, will not generate a value
1996 // if the return type is void. In such cases, a placeholder value
1997 // for the badly formed instruction is not needed. Hence, if Ty is
1998 // void, an error instruction is not appended.
Karl Schimpfaff9fa22014-10-29 14:32:07 -07001999 void appendErrorInstruction(Ice::Type Ty) {
2000 // Note: we don't worry about downstream translation errors because
2001 // the function will not be translated if any errors occur.
2002 if (Ty == Ice::IceType_void)
2003 return;
2004 Ice::Variable *Var = getNextInstVar(Ty);
Jim Stichnoth8e928382015-02-02 17:03:08 -08002005 CurrentNode->appendInst(Ice::InstAssign::create(Func.get(), Var, Var));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002006 }
Karl Schimpfd6064a12014-08-27 15:34:58 -07002007};
2008
Karl Schimpfd6064a12014-08-27 15:34:58 -07002009void FunctionParser::ExitBlock() {
Karl Schimpf6c17dd82015-06-30 10:25:27 -07002010 // Check if the last instruction in the function was terminating.
2011 if (!InstIsTerminating) {
2012 Error("Last instruction in function not terminator");
2013 if (isIRGenerationDisabled())
2014 return;
2015 // Recover by inserting an unreachable instruction.
2016 CurrentNode->appendInst(Ice::InstUnreachable::create(Func.get()));
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002017 }
Karl Schimpf98ed4462015-08-14 13:08:42 -07002018 ++CurrentBbIndex;
2019 if (CurrentBbIndex != DeclaredNumberBbs) {
2020 std::string Buffer;
2021 raw_string_ostream StrBuf(Buffer);
2022 StrBuf << "Function declared " << DeclaredNumberBbs
2023 << " basic blocks, but defined " << CurrentBbIndex << ".";
2024 Error(StrBuf.str());
2025 }
Karl Schimpf6c17dd82015-06-30 10:25:27 -07002026 if (isIRGenerationDisabled())
2027 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -07002028 // Before translating, check for blocks without instructions, and
2029 // insert unreachable. This shouldn't happen, but be safe.
Karl Schimpf74cd8832015-06-23 11:05:01 -07002030 size_t Index = 0;
Jim Stichnothf44f3712014-10-01 14:05:51 -07002031 for (Ice::CfgNode *Node : Func->getNodes()) {
Jim Stichnothbfb410d2014-11-05 16:04:05 -08002032 if (Node->getInsts().empty()) {
Karl Schimpfd6064a12014-08-27 15:34:58 -07002033 std::string Buffer;
2034 raw_string_ostream StrBuf(Buffer);
2035 StrBuf << "Basic block " << Index << " contains no instructions";
2036 Error(StrBuf.str());
Jim Stichnoth8e928382015-02-02 17:03:08 -08002037 Node->appendInst(Ice::InstUnreachable::create(Func.get()));
Karl Schimpfd6064a12014-08-27 15:34:58 -07002038 }
Jim Stichnothf44f3712014-10-01 14:05:51 -07002039 ++Index;
Karl Schimpfd6064a12014-08-27 15:34:58 -07002040 }
Jim Stichnoth69d3f9c2015-03-23 10:33:38 -07002041 Func->computeInOutEdges();
Karl Schimpfd6064a12014-08-27 15:34:58 -07002042}
2043
Karl Schimpf74cd8832015-06-23 11:05:01 -07002044void FunctionParser::reportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op,
Karl Schimpfd6064a12014-08-27 15:34:58 -07002045 Ice::Type OpTy) {
2046 std::string Buffer;
2047 raw_string_ostream StrBuf(Buffer);
2048 StrBuf << "Invalid operator type for " << Ice::InstArithmetic::getOpName(Op)
2049 << ". Found " << OpTy;
2050 Error(StrBuf.str());
2051}
2052
2053void FunctionParser::ProcessRecord() {
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002054 // Note: To better separate parse/IR generation times, when IR generation
2055 // is disabled we do the following:
2056 // 1) Delay exiting until after we extract operands.
2057 // 2) return before we access operands, since all operands will be a nullptr.
Karl Schimpfd6064a12014-08-27 15:34:58 -07002058 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
2059 if (InstIsTerminating) {
2060 InstIsTerminating = false;
Karl Schimpf98ed4462015-08-14 13:08:42 -07002061 ++CurrentBbIndex;
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002062 if (!isIRGenerationDisabled())
Karl Schimpf98ed4462015-08-14 13:08:42 -07002063 CurrentNode = getBasicBlock(CurrentBbIndex);
Karl Schimpfd6064a12014-08-27 15:34:58 -07002064 }
Karl Schimpf47661562014-09-11 14:42:49 -07002065 // The base index for relative indexing.
Karl Schimpf74cd8832015-06-23 11:05:01 -07002066 NaClBcIndexSize_t BaseIndex = getNextInstIndex();
Karl Schimpfd6064a12014-08-27 15:34:58 -07002067 switch (Record.GetCode()) {
2068 case naclbitc::FUNC_CODE_DECLAREBLOCKS: {
2069 // DECLAREBLOCKS: [n]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002070 if (!isValidRecordSize(1, "count"))
Karl Schimpfc0fdc272014-09-02 10:47:28 -07002071 return;
Karl Schimpf98ed4462015-08-14 13:08:42 -07002072 if (DeclaredNumberBbs > 0) {
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002073 Error("Duplicate function block count record");
2074 return;
2075 }
Karl Schimpf98ed4462015-08-14 13:08:42 -07002076
Karl Schimpf98ed4462015-08-14 13:08:42 -07002077 // Check for bad large sizes, since they can make ridiculous memory
Karl Schimpf7a993272015-08-17 12:43:29 -07002078 // requests and hang the user for large amounts of time.
2079 uint64_t NumBbs = Values[0];
2080 if (NumBbs > MaxRecordsInBlock) {
Karl Schimpf98ed4462015-08-14 13:08:42 -07002081 std::string Buffer;
2082 raw_string_ostream StrBuf(Buffer);
2083 StrBuf << "Function defines " << NumBbs
2084 << " basic blocks, which is too big for a function containing "
2085 << NumBytesDefiningFunction << " bytes";
2086 Error(StrBuf.str());
Karl Schimpf7a993272015-08-17 12:43:29 -07002087 NumBbs = MaxRecordsInBlock;
Karl Schimpf98ed4462015-08-14 13:08:42 -07002088 }
2089
2090 if (NumBbs == 0) {
2091 Error("Functions must contain at least one basic block.");
2092 NumBbs = 1;
2093 }
2094
2095 DeclaredNumberBbs = NumBbs;
2096 if (isIRGenerationDisabled())
2097 return;
2098 // Install the basic blocks, skipping bb0 which was created in the
2099 // constructor.
2100 for (size_t i = 1; i < NumBbs; ++i)
2101 installNextBasicBlock();
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002102 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -07002103 }
2104 case naclbitc::FUNC_CODE_INST_BINOP: {
2105 // BINOP: [opval, opval, opcode]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002106 if (!isValidRecordSize(3, "binop"))
Karl Schimpfc0fdc272014-09-02 10:47:28 -07002107 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002108 Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex);
2109 Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex);
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002110 if (isIRGenerationDisabled()) {
2111 assert(Op1 == nullptr && Op2 == nullptr);
2112 setNextLocalInstIndex(nullptr);
2113 return;
2114 }
Karl Schimpfd6064a12014-08-27 15:34:58 -07002115 Ice::Type Type1 = Op1->getType();
2116 Ice::Type Type2 = Op2->getType();
2117 if (Type1 != Type2) {
2118 std::string Buffer;
2119 raw_string_ostream StrBuf(Buffer);
2120 StrBuf << "Binop argument types differ: " << Type1 << " and " << Type2;
2121 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002122 appendErrorInstruction(Type1);
2123 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -07002124 }
2125
2126 Ice::InstArithmetic::OpKind Opcode;
Karl Schimpf9bb188d2014-12-10 12:54:34 -08002127 if (!convertBinopOpcode(Values[2], Type1, Opcode)) {
2128 appendErrorInstruction(Type1);
Karl Schimpfc0fdc272014-09-02 10:47:28 -07002129 return;
Karl Schimpf9bb188d2014-12-10 12:54:34 -08002130 }
Karl Schimpf47661562014-09-11 14:42:49 -07002131 CurrentNode->appendInst(Ice::InstArithmetic::create(
Jim Stichnoth8e928382015-02-02 17:03:08 -08002132 Func.get(), Opcode, getNextInstVar(Type1), Op1, Op2));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002133 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -07002134 }
Karl Schimpfc0fdc272014-09-02 10:47:28 -07002135 case naclbitc::FUNC_CODE_INST_CAST: {
2136 // CAST: [opval, destty, castopc]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002137 if (!isValidRecordSize(3, "cast"))
Karl Schimpfc0fdc272014-09-02 10:47:28 -07002138 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002139 Ice::Operand *Src = getRelativeOperand(Values[0], BaseIndex);
Karl Schimpf645aa1a2014-10-08 09:05:53 -07002140 Ice::Type CastType = Context->getSimpleTypeByID(Values[1]);
Karl Schimpfc0fdc272014-09-02 10:47:28 -07002141 Ice::InstCast::OpKind CastKind;
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002142 if (isIRGenerationDisabled()) {
2143 assert(Src == nullptr);
2144 setNextLocalInstIndex(nullptr);
2145 return;
2146 }
Karl Schimpfbf170372014-12-15 10:16:31 -08002147 if (!convertCastOpToIceOp(Values[2], Src->getType(), CastType, CastKind)) {
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002148 appendErrorInstruction(CastType);
Karl Schimpfc0fdc272014-09-02 10:47:28 -07002149 return;
2150 }
Jim Stichnoth8e928382015-02-02 17:03:08 -08002151 CurrentNode->appendInst(Ice::InstCast::create(
2152 Func.get(), CastKind, getNextInstVar(CastType), Src));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002153 return;
Karl Schimpfc0fdc272014-09-02 10:47:28 -07002154 }
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07002155 case naclbitc::FUNC_CODE_INST_VSELECT: {
2156 // VSELECT: [opval, opval, pred]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002157 if (!isValidRecordSize(3, "select"))
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002158 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002159 Ice::Operand *ThenVal = getRelativeOperand(Values[0], BaseIndex);
Karl Schimpf47661562014-09-11 14:42:49 -07002160 Ice::Operand *ElseVal = getRelativeOperand(Values[1], BaseIndex);
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002161 Ice::Operand *CondVal = getRelativeOperand(Values[2], BaseIndex);
2162 if (isIRGenerationDisabled()) {
2163 assert(ThenVal == nullptr && ElseVal == nullptr && CondVal == nullptr);
2164 setNextLocalInstIndex(nullptr);
2165 return;
2166 }
2167 Ice::Type ThenType = ThenVal->getType();
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07002168 Ice::Type ElseType = ElseVal->getType();
2169 if (ThenType != ElseType) {
2170 std::string Buffer;
2171 raw_string_ostream StrBuf(Buffer);
2172 StrBuf << "Select operands not same type. Found " << ThenType << " and "
2173 << ElseType;
2174 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002175 appendErrorInstruction(ThenType);
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07002176 return;
2177 }
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07002178 Ice::Type CondType = CondVal->getType();
2179 if (isVectorType(CondType)) {
2180 if (!isVectorType(ThenType) ||
2181 typeElementType(CondType) != Ice::IceType_i1 ||
2182 typeNumElements(ThenType) != typeNumElements(CondType)) {
2183 std::string Buffer;
2184 raw_string_ostream StrBuf(Buffer);
Karl Schimpf97501832014-09-16 13:35:32 -07002185 StrBuf << "Select condition type " << CondType
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07002186 << " not allowed for values of type " << ThenType;
2187 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002188 appendErrorInstruction(ThenType);
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07002189 return;
2190 }
2191 } else if (CondVal->getType() != Ice::IceType_i1) {
2192 std::string Buffer;
2193 raw_string_ostream StrBuf(Buffer);
Jim Stichnothdd842db2015-01-27 12:53:53 -08002194 StrBuf << "Select condition " << CondVal
2195 << " not type i1. Found: " << CondVal->getType();
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07002196 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002197 appendErrorInstruction(ThenType);
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07002198 return;
2199 }
Karl Schimpf47661562014-09-11 14:42:49 -07002200 CurrentNode->appendInst(Ice::InstSelect::create(
Jim Stichnoth8e928382015-02-02 17:03:08 -08002201 Func.get(), getNextInstVar(ThenType), CondVal, ThenVal, ElseVal));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002202 return;
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07002203 }
Karl Schimpf71ba8222014-09-03 09:46:24 -07002204 case naclbitc::FUNC_CODE_INST_EXTRACTELT: {
2205 // EXTRACTELT: [opval, opval]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002206 if (!isValidRecordSize(2, "extract element"))
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002207 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002208 Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex);
Karl Schimpf47661562014-09-11 14:42:49 -07002209 Ice::Operand *Index = getRelativeOperand(Values[1], BaseIndex);
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002210 if (isIRGenerationDisabled()) {
2211 assert(Vec == nullptr && Index == nullptr);
2212 setNextLocalInstIndex(nullptr);
2213 return;
2214 }
2215 Ice::Type VecType = Vec->getType();
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002216 VectorIndexCheckValue IndexCheckValue = validateVectorIndex(Vec, Index);
2217 if (IndexCheckValue != VectorIndexValid) {
Karl Schimpf71ba8222014-09-03 09:46:24 -07002218 std::string Buffer;
2219 raw_string_ostream StrBuf(Buffer);
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002220 dumpVectorIndexCheckValue(StrBuf, IndexCheckValue);
2221 StrBuf << ": extractelement " << VecType << " " << *Vec << ", "
2222 << Index->getType() << " " << *Index;
Karl Schimpf71ba8222014-09-03 09:46:24 -07002223 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002224 appendErrorInstruction(VecType);
2225 return;
Karl Schimpf71ba8222014-09-03 09:46:24 -07002226 }
Karl Schimpf47661562014-09-11 14:42:49 -07002227 CurrentNode->appendInst(Ice::InstExtractElement::create(
Jim Stichnoth8e928382015-02-02 17:03:08 -08002228 Func.get(), getNextInstVar(typeElementType(VecType)), Vec, Index));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002229 return;
Karl Schimpf71ba8222014-09-03 09:46:24 -07002230 }
2231 case naclbitc::FUNC_CODE_INST_INSERTELT: {
2232 // INSERTELT: [opval, opval, opval]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002233 if (!isValidRecordSize(3, "insert element"))
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002234 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002235 Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex);
Karl Schimpf47661562014-09-11 14:42:49 -07002236 Ice::Operand *Elt = getRelativeOperand(Values[1], BaseIndex);
Karl Schimpf47661562014-09-11 14:42:49 -07002237 Ice::Operand *Index = getRelativeOperand(Values[2], BaseIndex);
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002238 if (isIRGenerationDisabled()) {
2239 assert(Vec == nullptr && Elt == nullptr && Index == nullptr);
2240 setNextLocalInstIndex(nullptr);
2241 return;
2242 }
2243 Ice::Type VecType = Vec->getType();
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002244 VectorIndexCheckValue IndexCheckValue = validateVectorIndex(Vec, Index);
2245 if (IndexCheckValue != VectorIndexValid) {
Karl Schimpf71ba8222014-09-03 09:46:24 -07002246 std::string Buffer;
2247 raw_string_ostream StrBuf(Buffer);
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002248 dumpVectorIndexCheckValue(StrBuf, IndexCheckValue);
2249 StrBuf << ": insertelement " << VecType << " " << *Vec << ", "
2250 << Elt->getType() << " " << *Elt << ", " << Index->getType() << " "
2251 << *Index;
Karl Schimpf71ba8222014-09-03 09:46:24 -07002252 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002253 appendErrorInstruction(Elt->getType());
2254 return;
Karl Schimpf71ba8222014-09-03 09:46:24 -07002255 }
Karl Schimpf47661562014-09-11 14:42:49 -07002256 CurrentNode->appendInst(Ice::InstInsertElement::create(
Jim Stichnoth8e928382015-02-02 17:03:08 -08002257 Func.get(), getNextInstVar(VecType), Vec, Elt, Index));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002258 return;
Karl Schimpf71ba8222014-09-03 09:46:24 -07002259 }
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002260 case naclbitc::FUNC_CODE_INST_CMP2: {
2261 // CMP2: [opval, opval, pred]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002262 if (!isValidRecordSize(3, "compare"))
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002263 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002264 Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex);
2265 Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex);
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002266 if (isIRGenerationDisabled()) {
2267 assert(Op1 == nullptr && Op2 == nullptr);
2268 setNextLocalInstIndex(nullptr);
2269 return;
2270 }
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002271 Ice::Type Op1Type = Op1->getType();
2272 Ice::Type Op2Type = Op2->getType();
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002273 Ice::Type DestType = getCompareResultType(Op1Type);
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002274 if (Op1Type != Op2Type) {
2275 std::string Buffer;
2276 raw_string_ostream StrBuf(Buffer);
Jim Stichnothdd842db2015-01-27 12:53:53 -08002277 StrBuf << "Compare argument types differ: " << Op1Type << " and "
2278 << Op2Type;
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002279 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002280 appendErrorInstruction(DestType);
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002281 Op2 = Op1;
2282 }
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002283 if (DestType == Ice::IceType_void) {
2284 std::string Buffer;
2285 raw_string_ostream StrBuf(Buffer);
2286 StrBuf << "Compare not defined for type " << Op1Type;
2287 Error(StrBuf.str());
2288 return;
2289 }
Karl Schimpf47661562014-09-11 14:42:49 -07002290 Ice::Variable *Dest = getNextInstVar(DestType);
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002291 if (isIntegerType(Op1Type)) {
2292 Ice::InstIcmp::ICond Cond;
2293 if (!convertNaClBitcICmpOpToIce(Values[2], Cond)) {
2294 std::string Buffer;
2295 raw_string_ostream StrBuf(Buffer);
2296 StrBuf << "Compare record contains unknown integer predicate index: "
2297 << Values[2];
2298 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002299 appendErrorInstruction(DestType);
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002300 }
Karl Schimpf47661562014-09-11 14:42:49 -07002301 CurrentNode->appendInst(
Jim Stichnoth8e928382015-02-02 17:03:08 -08002302 Ice::InstIcmp::create(Func.get(), Cond, Dest, Op1, Op2));
Jim Stichnothdd842db2015-01-27 12:53:53 -08002303 } else if (isFloatingType(Op1Type)) {
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002304 Ice::InstFcmp::FCond Cond;
2305 if (!convertNaClBitcFCompOpToIce(Values[2], Cond)) {
2306 std::string Buffer;
2307 raw_string_ostream StrBuf(Buffer);
2308 StrBuf << "Compare record contains unknown float predicate index: "
2309 << Values[2];
2310 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002311 appendErrorInstruction(DestType);
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002312 }
Karl Schimpf47661562014-09-11 14:42:49 -07002313 CurrentNode->appendInst(
Jim Stichnoth8e928382015-02-02 17:03:08 -08002314 Ice::InstFcmp::create(Func.get(), Cond, Dest, Op1, Op2));
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002315 } else {
2316 // Not sure this can happen, but be safe.
2317 std::string Buffer;
2318 raw_string_ostream StrBuf(Buffer);
2319 StrBuf << "Compare on type not understood: " << Op1Type;
2320 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002321 appendErrorInstruction(DestType);
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002322 return;
2323 }
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002324 return;
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002325 }
Karl Schimpfd6064a12014-08-27 15:34:58 -07002326 case naclbitc::FUNC_CODE_INST_RET: {
2327 // RET: [opval?]
Karl Schimpf6c17dd82015-06-30 10:25:27 -07002328 InstIsTerminating = true;
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002329 if (!isValidRecordSizeInRange(0, 1, "return"))
Karl Schimpfc0fdc272014-09-02 10:47:28 -07002330 return;
Jim Stichnothbfb410d2014-11-05 16:04:05 -08002331 if (Values.empty()) {
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002332 if (isIRGenerationDisabled())
2333 return;
Jim Stichnoth8e928382015-02-02 17:03:08 -08002334 CurrentNode->appendInst(Ice::InstRet::create(Func.get()));
Karl Schimpfd6064a12014-08-27 15:34:58 -07002335 } else {
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002336 Ice::Operand *RetVal = getRelativeOperand(Values[0], BaseIndex);
2337 if (isIRGenerationDisabled()) {
2338 assert(RetVal == nullptr);
2339 return;
2340 }
Jim Stichnoth8e928382015-02-02 17:03:08 -08002341 CurrentNode->appendInst(Ice::InstRet::create(Func.get(), RetVal));
Karl Schimpfd6064a12014-08-27 15:34:58 -07002342 }
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002343 return;
Karl Schimpfc836acb2014-09-05 08:32:47 -07002344 }
2345 case naclbitc::FUNC_CODE_INST_BR: {
Karl Schimpf6c17dd82015-06-30 10:25:27 -07002346 InstIsTerminating = true;
Karl Schimpfc836acb2014-09-05 08:32:47 -07002347 if (Values.size() == 1) {
2348 // BR: [bb#]
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002349 if (isIRGenerationDisabled())
2350 return;
Karl Schimpfc836acb2014-09-05 08:32:47 -07002351 Ice::CfgNode *Block = getBranchBasicBlock(Values[0]);
Karl Schimpfe3f64d02014-10-07 10:38:22 -07002352 if (Block == nullptr)
Karl Schimpfc836acb2014-09-05 08:32:47 -07002353 return;
Jim Stichnoth8e928382015-02-02 17:03:08 -08002354 CurrentNode->appendInst(Ice::InstBr::create(Func.get(), Block));
Karl Schimpfc836acb2014-09-05 08:32:47 -07002355 } else {
2356 // BR: [bb#, bb#, opval]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002357 if (!isValidRecordSize(3, "branch"))
Karl Schimpfc836acb2014-09-05 08:32:47 -07002358 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002359 Ice::Operand *Cond = getRelativeOperand(Values[2], BaseIndex);
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002360 if (isIRGenerationDisabled()) {
2361 assert(Cond == nullptr);
2362 return;
2363 }
Karl Schimpfc836acb2014-09-05 08:32:47 -07002364 if (Cond->getType() != Ice::IceType_i1) {
2365 std::string Buffer;
2366 raw_string_ostream StrBuf(Buffer);
Jim Stichnothdd842db2015-01-27 12:53:53 -08002367 StrBuf << "Branch condition " << *Cond
2368 << " not i1. Found: " << Cond->getType();
Karl Schimpfc836acb2014-09-05 08:32:47 -07002369 Error(StrBuf.str());
2370 return;
2371 }
2372 Ice::CfgNode *ThenBlock = getBranchBasicBlock(Values[0]);
2373 Ice::CfgNode *ElseBlock = getBranchBasicBlock(Values[1]);
Karl Schimpfe3f64d02014-10-07 10:38:22 -07002374 if (ThenBlock == nullptr || ElseBlock == nullptr)
Karl Schimpfc836acb2014-09-05 08:32:47 -07002375 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002376 CurrentNode->appendInst(
Jim Stichnoth8e928382015-02-02 17:03:08 -08002377 Ice::InstBr::create(Func.get(), Cond, ThenBlock, ElseBlock));
Karl Schimpfc836acb2014-09-05 08:32:47 -07002378 }
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002379 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -07002380 }
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002381 case naclbitc::FUNC_CODE_INST_SWITCH: {
2382 // SWITCH: [Condty, Cond, BbIndex, NumCases Case ...]
2383 // where Case = [1, 1, Value, BbIndex].
2384 //
2385 // Note: Unlike most instructions, we don't infer the type of
2386 // Cond, but provide it as a separate field. There are also
2387 // unnecesary data fields (i.e. constants 1). These were not
2388 // cleaned up in PNaCl bitcode because the bitcode format was
2389 // already frozen when the problem was noticed.
Karl Schimpf6c17dd82015-06-30 10:25:27 -07002390 InstIsTerminating = true;
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002391 if (!isValidRecordSizeAtLeast(4, "switch"))
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002392 return;
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002393
Karl Schimpf645aa1a2014-10-08 09:05:53 -07002394 Ice::Type CondTy = Context->getSimpleTypeByID(Values[0]);
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002395 if (!Ice::isScalarIntegerType(CondTy)) {
2396 std::string Buffer;
2397 raw_string_ostream StrBuf(Buffer);
2398 StrBuf << "Case condition must be non-wide integer. Found: " << CondTy;
2399 Error(StrBuf.str());
2400 return;
2401 }
2402 Ice::SizeT BitWidth = Ice::getScalarIntBitWidth(CondTy);
2403 Ice::Operand *Cond = getRelativeOperand(Values[1], BaseIndex);
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002404
2405 const bool isIRGenDisabled = isIRGenerationDisabled();
2406 if (isIRGenDisabled) {
2407 assert(Cond == nullptr);
2408 } else if (CondTy != Cond->getType()) {
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002409 std::string Buffer;
2410 raw_string_ostream StrBuf(Buffer);
2411 StrBuf << "Case condition expects type " << CondTy
2412 << ". Found: " << Cond->getType();
2413 Error(StrBuf.str());
2414 return;
2415 }
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002416 Ice::CfgNode *DefaultLabel =
2417 isIRGenDisabled ? nullptr : getBranchBasicBlock(Values[2]);
Karl Schimpf74cd8832015-06-23 11:05:01 -07002418 uint64_t NumCasesRaw = Values[3];
2419 if (NumCasesRaw > std::numeric_limits<uint32_t>::max()) {
2420 std::string Buffer;
2421 raw_string_ostream StrBuf(Buffer);
2422 StrBuf << "Too many cases specified in switch: " << NumCasesRaw;
2423 Error(StrBuf.str());
2424 NumCasesRaw = std::numeric_limits<uint32_t>::max();
2425 }
2426 uint32_t NumCases = NumCasesRaw;
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002427
2428 // Now recognize each of the cases.
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002429 if (!isValidRecordSize(4 + NumCases * 4, "switch"))
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002430 return;
2431 Ice::InstSwitch *Switch =
Jim Stichnoth8e928382015-02-02 17:03:08 -08002432 isIRGenDisabled
2433 ? nullptr
2434 : Ice::InstSwitch::create(Func.get(), NumCases, Cond, DefaultLabel);
Jim Stichnothdd842db2015-01-27 12:53:53 -08002435 unsigned ValCaseIndex = 4; // index to beginning of case entry.
Karl Schimpf74cd8832015-06-23 11:05:01 -07002436 for (uint32_t CaseIndex = 0; CaseIndex < NumCases;
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002437 ++CaseIndex, ValCaseIndex += 4) {
Jim Stichnothdd842db2015-01-27 12:53:53 -08002438 if (Values[ValCaseIndex] != 1 || Values[ValCaseIndex + 1] != 1) {
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002439 std::string Buffer;
2440 raw_string_ostream StrBuf(Buffer);
2441 StrBuf << "Sequence [1, 1, value, label] expected for case entry "
2442 << "in switch record. (at index" << ValCaseIndex << ")";
2443 Error(StrBuf.str());
2444 return;
2445 }
Karl Schimpf32817482014-12-15 09:52:26 -08002446 Ice::APInt Value(BitWidth,
2447 NaClDecodeSignRotatedValue(Values[ValCaseIndex + 2]));
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002448 if (isIRGenDisabled)
2449 continue;
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002450 Ice::CfgNode *Label = getBranchBasicBlock(Values[ValCaseIndex + 3]);
2451 Switch->addBranch(CaseIndex, Value.getSExtValue(), Label);
2452 }
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002453 if (isIRGenDisabled)
2454 return;
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002455 CurrentNode->appendInst(Switch);
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002456 return;
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002457 }
Karl Schimpf97501832014-09-16 13:35:32 -07002458 case naclbitc::FUNC_CODE_INST_UNREACHABLE: {
2459 // UNREACHABLE: []
Karl Schimpf6c17dd82015-06-30 10:25:27 -07002460 InstIsTerminating = true;
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002461 if (!isValidRecordSize(0, "unreachable"))
Karl Schimpf97501832014-09-16 13:35:32 -07002462 return;
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002463 if (isIRGenerationDisabled())
2464 return;
Jim Stichnoth8e928382015-02-02 17:03:08 -08002465 CurrentNode->appendInst(Ice::InstUnreachable::create(Func.get()));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002466 return;
Karl Schimpf97501832014-09-16 13:35:32 -07002467 }
Karl Schimpf47661562014-09-11 14:42:49 -07002468 case naclbitc::FUNC_CODE_INST_PHI: {
2469 // PHI: [ty, val1, bb1, ..., valN, bbN] for n >= 2.
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002470 if (!isValidRecordSizeAtLeast(3, "phi"))
Karl Schimpf47661562014-09-11 14:42:49 -07002471 return;
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002472 Ice::Type Ty = Context->getSimpleTypeByID(Values[0]);
Karl Schimpf47661562014-09-11 14:42:49 -07002473 if ((Values.size() & 0x1) == 0) {
2474 // Not an odd number of values.
2475 std::string Buffer;
2476 raw_string_ostream StrBuf(Buffer);
2477 StrBuf << "function block phi record size not valid: " << Values.size();
2478 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002479 appendErrorInstruction(Ty);
Karl Schimpf47661562014-09-11 14:42:49 -07002480 return;
2481 }
Karl Schimpf47661562014-09-11 14:42:49 -07002482 if (Ty == Ice::IceType_void) {
2483 Error("Phi record using type void not allowed");
2484 return;
2485 }
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002486 if (isIRGenerationDisabled()) {
2487 // Verify arguments are defined before quitting.
2488 for (unsigned i = 1; i < Values.size(); i += 2) {
2489 assert(getRelativeOperand(NaClDecodeSignRotatedValue(Values[i]),
2490 BaseIndex) == nullptr);
2491 }
2492 setNextLocalInstIndex(nullptr);
2493 return;
2494 }
Karl Schimpf47661562014-09-11 14:42:49 -07002495 Ice::Variable *Dest = getNextInstVar(Ty);
Jim Stichnoth8e928382015-02-02 17:03:08 -08002496 Ice::InstPhi *Phi =
2497 Ice::InstPhi::create(Func.get(), Values.size() >> 1, Dest);
Karl Schimpf74cd8832015-06-23 11:05:01 -07002498 for (size_t i = 1; i < Values.size(); i += 2) {
Karl Schimpf47661562014-09-11 14:42:49 -07002499 Ice::Operand *Op =
2500 getRelativeOperand(NaClDecodeSignRotatedValue(Values[i]), BaseIndex);
2501 if (Op->getType() != Ty) {
2502 std::string Buffer;
2503 raw_string_ostream StrBuf(Buffer);
Karl Schimpf97501832014-09-16 13:35:32 -07002504 StrBuf << "Value " << *Op << " not type " << Ty
2505 << " in phi instruction. Found: " << Op->getType();
Karl Schimpf47661562014-09-11 14:42:49 -07002506 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002507 appendErrorInstruction(Ty);
Karl Schimpf47661562014-09-11 14:42:49 -07002508 return;
2509 }
2510 Phi->addArgument(Op, getBasicBlock(Values[i + 1]));
2511 }
2512 CurrentNode->appendInst(Phi);
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002513 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002514 }
Karl Schimpf742d72d2014-09-09 11:40:09 -07002515 case naclbitc::FUNC_CODE_INST_ALLOCA: {
2516 // ALLOCA: [Size, align]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002517 if (!isValidRecordSize(2, "alloca"))
Karl Schimpf742d72d2014-09-09 11:40:09 -07002518 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002519 Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex);
Karl Schimpff875d452014-12-09 13:50:07 -08002520 uint32_t Alignment;
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002521 extractAlignment("Alloca", Values[1], Alignment);
2522 if (isIRGenerationDisabled()) {
2523 assert(ByteCount == nullptr);
2524 setNextLocalInstIndex(nullptr);
2525 return;
2526 }
Karl Schimpf4019f082014-12-15 13:45:00 -08002527 Ice::Type PtrTy = Ice::getPointerType();
Karl Schimpf742d72d2014-09-09 11:40:09 -07002528 if (ByteCount->getType() != Ice::IceType_i32) {
2529 std::string Buffer;
2530 raw_string_ostream StrBuf(Buffer);
Karl Schimpf97501832014-09-16 13:35:32 -07002531 StrBuf << "Alloca on non-i32 value. Found: " << *ByteCount;
Karl Schimpf742d72d2014-09-09 11:40:09 -07002532 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002533 appendErrorInstruction(PtrTy);
Karl Schimpf742d72d2014-09-09 11:40:09 -07002534 return;
2535 }
Jim Stichnoth8e928382015-02-02 17:03:08 -08002536 CurrentNode->appendInst(Ice::InstAlloca::create(
2537 Func.get(), ByteCount, Alignment, getNextInstVar(PtrTy)));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002538 return;
Karl Schimpf742d72d2014-09-09 11:40:09 -07002539 }
Karl Schimpf41689df2014-09-10 14:36:07 -07002540 case naclbitc::FUNC_CODE_INST_LOAD: {
2541 // LOAD: [address, align, ty]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002542 if (!isValidRecordSize(3, "load"))
Karl Schimpf41689df2014-09-10 14:36:07 -07002543 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002544 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex);
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002545 Ice::Type Ty = Context->getSimpleTypeByID(Values[2]);
Karl Schimpff875d452014-12-09 13:50:07 -08002546 uint32_t Alignment;
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002547 extractAlignment("Load", Values[1], Alignment);
2548 if (isIRGenerationDisabled()) {
2549 assert(Address == nullptr);
2550 setNextLocalInstIndex(nullptr);
2551 return;
2552 }
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002553 if (!isValidPointerType(Address, "Load")) {
2554 appendErrorInstruction(Ty);
Karl Schimpf41689df2014-09-10 14:36:07 -07002555 return;
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002556 }
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002557 if (!isValidLoadStoreAlignment(Alignment, Ty, "Load")) {
2558 appendErrorInstruction(Ty);
Karl Schimpf41689df2014-09-10 14:36:07 -07002559 return;
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002560 }
Jim Stichnoth8e928382015-02-02 17:03:08 -08002561 CurrentNode->appendInst(Ice::InstLoad::create(
2562 Func.get(), getNextInstVar(Ty), Address, Alignment));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002563 return;
Karl Schimpf41689df2014-09-10 14:36:07 -07002564 }
2565 case naclbitc::FUNC_CODE_INST_STORE: {
2566 // STORE: [address, value, align]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002567 if (!isValidRecordSize(3, "store"))
Karl Schimpf41689df2014-09-10 14:36:07 -07002568 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002569 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex);
Karl Schimpf47661562014-09-11 14:42:49 -07002570 Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex);
Karl Schimpff875d452014-12-09 13:50:07 -08002571 uint32_t Alignment;
Karl Schimpf64dcde72014-09-10 15:02:08 -07002572 extractAlignment("Store", Values[2], Alignment);
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002573 if (isIRGenerationDisabled()) {
2574 assert(Address == nullptr && Value == nullptr);
2575 return;
2576 }
2577 if (!isValidPointerType(Address, "Store"))
2578 return;
Karl Schimpf41689df2014-09-10 14:36:07 -07002579 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store"))
2580 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002581 CurrentNode->appendInst(
Jim Stichnoth8e928382015-02-02 17:03:08 -08002582 Ice::InstStore::create(Func.get(), Value, Address, Alignment));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002583 return;
Karl Schimpf41689df2014-09-10 14:36:07 -07002584 }
Karl Schimpf8df26f32014-09-19 09:33:26 -07002585 case naclbitc::FUNC_CODE_INST_CALL:
2586 case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: {
2587 // CALL: [cc, fnid, arg0, arg1...]
2588 // CALL_INDIRECT: [cc, fn, returnty, args...]
2589 //
2590 // Note: The difference between CALL and CALL_INDIRECT is that
Karl Schimpf9d98d792014-10-13 15:01:08 -07002591 // CALL has a reference to an explicit function declaration, while
2592 // the CALL_INDIRECT is just an address. For CALL, we can infer
2593 // the return type by looking up the type signature associated
2594 // with the function declaration. For CALL_INDIRECT we can only
2595 // infer the type signature via argument types, and the
2596 // corresponding return type stored in CALL_INDIRECT record.
Karl Schimpf8df26f32014-09-19 09:33:26 -07002597 Ice::SizeT ParamsStartIndex = 2;
2598 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) {
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002599 if (!isValidRecordSizeAtLeast(2, "call"))
Karl Schimpf8df26f32014-09-19 09:33:26 -07002600 return;
2601 } else {
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002602 if (!isValidRecordSizeAtLeast(3, "call indirect"))
Karl Schimpf8df26f32014-09-19 09:33:26 -07002603 return;
2604 ParamsStartIndex = 3;
2605 }
2606
Karl Schimpf8df26f32014-09-19 09:33:26 -07002607 // Extract out the called function and its return type.
2608 uint32_t CalleeIndex = convertRelativeToAbsIndex(Values[1], BaseIndex);
2609 Ice::Operand *Callee = getOperand(CalleeIndex);
2610 Ice::Type ReturnType = Ice::IceType_void;
Karl Schimpfe3f64d02014-10-07 10:38:22 -07002611 const Ice::Intrinsics::FullIntrinsicInfo *IntrinsicInfo = nullptr;
Karl Schimpf8df26f32014-09-19 09:33:26 -07002612 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) {
Karl Schimpf9d98d792014-10-13 15:01:08 -07002613 Ice::FunctionDeclaration *Fcn = Context->getFunctionByID(CalleeIndex);
2614 const Ice::FuncSigType &Signature = Fcn->getSignature();
2615 ReturnType = Signature.getReturnType();
Karl Schimpf8df26f32014-09-19 09:33:26 -07002616
2617 // Check if this direct call is to an Intrinsic (starts with "llvm.")
Jim Stichnotha67fc442015-03-03 16:13:11 -08002618 bool BadIntrinsic;
Jan Voungc9ec5792015-02-05 17:31:28 -08002619 const Ice::IceString &Name = Fcn->getName();
Jim Stichnotha67fc442015-03-03 16:13:11 -08002620 IntrinsicInfo = getTranslator().getContext()->getIntrinsicsInfo().find(
2621 Name, BadIntrinsic);
2622 if (BadIntrinsic) {
2623 std::string Buffer;
2624 raw_string_ostream StrBuf(Buffer);
2625 StrBuf << "Invalid PNaCl intrinsic call to " << Name;
2626 Error(StrBuf.str());
2627 appendErrorInstruction(ReturnType);
2628 return;
Karl Schimpf8df26f32014-09-19 09:33:26 -07002629 }
2630 } else {
Karl Schimpf645aa1a2014-10-08 09:05:53 -07002631 ReturnType = Context->getSimpleTypeByID(Values[2]);
Karl Schimpf8df26f32014-09-19 09:33:26 -07002632 }
2633
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002634 // Extract call information.
2635 uint64_t CCInfo = Values[0];
2636 CallingConv::ID CallingConv;
2637 if (!naclbitc::DecodeCallingConv(CCInfo >> 1, CallingConv)) {
2638 std::string Buffer;
2639 raw_string_ostream StrBuf(Buffer);
2640 StrBuf << "Function call calling convention value " << (CCInfo >> 1)
2641 << " not understood.";
2642 Error(StrBuf.str());
2643 appendErrorInstruction(ReturnType);
2644 return;
2645 }
2646 bool IsTailCall = static_cast<bool>(CCInfo & 1);
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002647 Ice::SizeT NumParams = Values.size() - ParamsStartIndex;
2648
2649 if (isIRGenerationDisabled()) {
2650 assert(Callee == nullptr);
2651 // Check that parameters are defined.
2652 for (Ice::SizeT ParamIndex = 0; ParamIndex < NumParams; ++ParamIndex) {
2653 assert(getRelativeOperand(Values[ParamsStartIndex + ParamIndex],
2654 BaseIndex) == nullptr);
2655 }
2656 // Define value slot only if value returned.
2657 if (ReturnType != Ice::IceType_void)
2658 setNextLocalInstIndex(nullptr);
2659 return;
2660 }
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002661
Karl Schimpf8df26f32014-09-19 09:33:26 -07002662 // Create the call instruction.
Karl Schimpfe3f64d02014-10-07 10:38:22 -07002663 Ice::Variable *Dest = (ReturnType == Ice::IceType_void)
2664 ? nullptr
2665 : getNextInstVar(ReturnType);
Karl Schimpfe3f64d02014-10-07 10:38:22 -07002666 Ice::InstCall *Inst = nullptr;
Karl Schimpf8df26f32014-09-19 09:33:26 -07002667 if (IntrinsicInfo) {
Jim Stichnoth8e928382015-02-02 17:03:08 -08002668 Inst = Ice::InstIntrinsicCall::create(Func.get(), NumParams, Dest, Callee,
Jim Stichnothdd842db2015-01-27 12:53:53 -08002669 IntrinsicInfo->Info);
Karl Schimpf8df26f32014-09-19 09:33:26 -07002670 } else {
Jim Stichnoth8e928382015-02-02 17:03:08 -08002671 Inst = Ice::InstCall::create(Func.get(), NumParams, Dest, Callee,
2672 IsTailCall);
Karl Schimpf8df26f32014-09-19 09:33:26 -07002673 }
2674
2675 // Add parameters.
2676 for (Ice::SizeT ParamIndex = 0; ParamIndex < NumParams; ++ParamIndex) {
2677 Inst->addArg(
2678 getRelativeOperand(Values[ParamsStartIndex + ParamIndex], BaseIndex));
2679 }
2680
2681 // If intrinsic call, validate call signature.
2682 if (IntrinsicInfo) {
2683 Ice::SizeT ArgIndex = 0;
2684 switch (IntrinsicInfo->validateCall(Inst, ArgIndex)) {
Karl Schimpf8df26f32014-09-19 09:33:26 -07002685 case Ice::Intrinsics::IsValidCall:
2686 break;
2687 case Ice::Intrinsics::BadReturnType: {
2688 std::string Buffer;
2689 raw_string_ostream StrBuf(Buffer);
2690 StrBuf << "Intrinsic call expects return type "
2691 << IntrinsicInfo->getReturnType()
2692 << ". Found: " << Inst->getReturnType();
2693 Error(StrBuf.str());
Karl Schimpf8df26f32014-09-19 09:33:26 -07002694 break;
2695 }
2696 case Ice::Intrinsics::WrongNumOfArgs: {
2697 std::string Buffer;
2698 raw_string_ostream StrBuf(Buffer);
2699 StrBuf << "Intrinsic call expects " << IntrinsicInfo->getNumArgs()
2700 << ". Found: " << Inst->getNumArgs();
2701 Error(StrBuf.str());
Karl Schimpf8df26f32014-09-19 09:33:26 -07002702 break;
2703 }
2704 case Ice::Intrinsics::WrongCallArgType: {
2705 std::string Buffer;
2706 raw_string_ostream StrBuf(Buffer);
2707 StrBuf << "Intrinsic call argument " << ArgIndex << " expects type "
2708 << IntrinsicInfo->getArgType(ArgIndex)
2709 << ". Found: " << Inst->getArg(ArgIndex)->getType();
2710 Error(StrBuf.str());
Karl Schimpf8df26f32014-09-19 09:33:26 -07002711 break;
2712 }
2713 }
2714 }
2715
2716 CurrentNode->appendInst(Inst);
2717 return;
2718 }
Karl Schimpf8f07aa82014-09-17 09:07:20 -07002719 case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF: {
2720 // FORWARDTYPEREF: [opval, ty]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002721 if (!isValidRecordSize(2, "forward type ref"))
Karl Schimpf8f07aa82014-09-17 09:07:20 -07002722 return;
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002723 Ice::Type OpType = Context->getSimpleTypeByID(Values[1]);
2724 setOperand(Values[0],
2725 isIRGenerationDisabled() ? nullptr : createInstVar(OpType));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002726 return;
Karl Schimpf8f07aa82014-09-17 09:07:20 -07002727 }
Karl Schimpfd6064a12014-08-27 15:34:58 -07002728 default:
2729 // Generate error message!
2730 BlockParserBaseClass::ProcessRecord();
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002731 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -07002732 }
Karl Schimpfd6064a12014-08-27 15:34:58 -07002733}
2734
Karl Schimpff12355e2014-09-08 13:41:09 -07002735/// Parses constants within a function block.
2736class ConstantsParser : public BlockParserBaseClass {
Jim Stichnothc6ead202015-02-24 09:30:30 -08002737 ConstantsParser() = delete;
Jim Stichnoth0795ba02014-10-01 14:23:01 -07002738 ConstantsParser(const ConstantsParser &) = delete;
2739 ConstantsParser &operator=(const ConstantsParser &) = delete;
Karl Schimpff12355e2014-09-08 13:41:09 -07002740
2741public:
2742 ConstantsParser(unsigned BlockID, FunctionParser *FuncParser)
Karl Schimpf58455872014-11-03 11:29:39 -08002743 : BlockParserBaseClass(BlockID, FuncParser),
2744 Timer(Ice::TimerStack::TT_parseConstants, getTranslator().getContext()),
Jim Stichnotheafb56c2015-06-22 10:35:22 -07002745 FuncParser(FuncParser) {}
Karl Schimpff12355e2014-09-08 13:41:09 -07002746
Jim Stichnothe587d942015-06-22 15:49:04 -07002747 ~ConstantsParser() override = default;
Karl Schimpff12355e2014-09-08 13:41:09 -07002748
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002749 const char *getBlockName() const override { return "constants"; }
2750
Karl Schimpff12355e2014-09-08 13:41:09 -07002751private:
Karl Schimpf58455872014-11-03 11:29:39 -08002752 Ice::TimerMarker Timer;
Karl Schimpff12355e2014-09-08 13:41:09 -07002753 // The parser of the function block this constants block appears in.
2754 FunctionParser *FuncParser;
2755 // The type to use for succeeding constants.
Jim Stichnotheafb56c2015-06-22 10:35:22 -07002756 Ice::Type NextConstantType = Ice::IceType_void;
Karl Schimpff12355e2014-09-08 13:41:09 -07002757
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07002758 void ProcessRecord() override;
Karl Schimpff12355e2014-09-08 13:41:09 -07002759
2760 Ice::GlobalContext *getContext() { return getTranslator().getContext(); }
2761
2762 // Returns true if the type to use for succeeding constants is defined.
2763 // If false, also generates an error message.
2764 bool isValidNextConstantType() {
2765 if (NextConstantType != Ice::IceType_void)
2766 return true;
2767 Error("Constant record not preceded by set type record");
2768 return false;
2769 }
2770};
2771
2772void ConstantsParser::ProcessRecord() {
2773 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
2774 switch (Record.GetCode()) {
2775 case naclbitc::CST_CODE_SETTYPE: {
2776 // SETTYPE: [typeid]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002777 if (!isValidRecordSize(1, "set type"))
Karl Schimpff12355e2014-09-08 13:41:09 -07002778 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -07002779 NextConstantType = Context->getSimpleTypeByID(Values[0]);
Karl Schimpff12355e2014-09-08 13:41:09 -07002780 if (NextConstantType == Ice::IceType_void)
2781 Error("constants block set type not allowed for void type");
2782 return;
2783 }
2784 case naclbitc::CST_CODE_UNDEF: {
2785 // UNDEF
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002786 if (!isValidRecordSize(0, "undef"))
Karl Schimpff12355e2014-09-08 13:41:09 -07002787 return;
2788 if (!isValidNextConstantType())
2789 return;
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002790 if (isIRGenerationDisabled()) {
2791 FuncParser->setNextConstantID(nullptr);
2792 return;
2793 }
Karl Schimpff12355e2014-09-08 13:41:09 -07002794 FuncParser->setNextConstantID(
2795 getContext()->getConstantUndef(NextConstantType));
2796 return;
2797 }
2798 case naclbitc::CST_CODE_INTEGER: {
2799 // INTEGER: [intval]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002800 if (!isValidRecordSize(1, "integer"))
Karl Schimpff12355e2014-09-08 13:41:09 -07002801 return;
2802 if (!isValidNextConstantType())
2803 return;
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002804 if (isIRGenerationDisabled()) {
2805 FuncParser->setNextConstantID(nullptr);
2806 return;
2807 }
Karl Schimpf4019f082014-12-15 13:45:00 -08002808 if (Ice::isScalarIntegerType(NextConstantType)) {
2809 Ice::APInt Value(Ice::getScalarIntBitWidth(NextConstantType),
Karl Schimpf32817482014-12-15 09:52:26 -08002810 NaClDecodeSignRotatedValue(Values[0]));
Jim Stichnothd2cb4362014-11-20 11:24:42 -08002811 if (Ice::Constant *C = getContext()->getConstantInt(
2812 NextConstantType, Value.getSExtValue())) {
2813 FuncParser->setNextConstantID(C);
2814 return;
2815 }
Karl Schimpff12355e2014-09-08 13:41:09 -07002816 }
2817 std::string Buffer;
2818 raw_string_ostream StrBuf(Buffer);
2819 StrBuf << "constant block integer record for non-integer type "
2820 << NextConstantType;
2821 Error(StrBuf.str());
2822 return;
2823 }
2824 case naclbitc::CST_CODE_FLOAT: {
2825 // FLOAT: [fpval]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002826 if (!isValidRecordSize(1, "float"))
Karl Schimpff12355e2014-09-08 13:41:09 -07002827 return;
2828 if (!isValidNextConstantType())
2829 return;
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002830 if (isIRGenerationDisabled()) {
2831 FuncParser->setNextConstantID(nullptr);
2832 return;
2833 }
Karl Schimpff12355e2014-09-08 13:41:09 -07002834 switch (NextConstantType) {
2835 case Ice::IceType_f32: {
Karl Schimpf32817482014-12-15 09:52:26 -08002836 const Ice::APInt IntValue(32, static_cast<uint32_t>(Values[0]));
2837 float FpValue = Ice::convertAPIntToFp<int32_t, float>(IntValue);
2838 FuncParser->setNextConstantID(getContext()->getConstantFloat(FpValue));
Karl Schimpff12355e2014-09-08 13:41:09 -07002839 return;
2840 }
2841 case Ice::IceType_f64: {
Karl Schimpf32817482014-12-15 09:52:26 -08002842 const Ice::APInt IntValue(64, Values[0]);
2843 double FpValue = Ice::convertAPIntToFp<uint64_t, double>(IntValue);
2844 FuncParser->setNextConstantID(getContext()->getConstantDouble(FpValue));
Karl Schimpff12355e2014-09-08 13:41:09 -07002845 return;
2846 }
2847 default: {
2848 std::string Buffer;
2849 raw_string_ostream StrBuf(Buffer);
2850 StrBuf << "constant block float record for non-floating type "
2851 << NextConstantType;
2852 Error(StrBuf.str());
2853 return;
2854 }
2855 }
2856 }
2857 default:
2858 // Generate error message!
2859 BlockParserBaseClass::ProcessRecord();
2860 return;
2861 }
2862}
2863
Karl Schimpfc132b762014-09-11 09:43:47 -07002864// Parses valuesymtab blocks appearing in a function block.
2865class FunctionValuesymtabParser : public ValuesymtabParser {
Jim Stichnothc6ead202015-02-24 09:30:30 -08002866 FunctionValuesymtabParser() = delete;
Jim Stichnoth0795ba02014-10-01 14:23:01 -07002867 FunctionValuesymtabParser(const FunctionValuesymtabParser &) = delete;
2868 void operator=(const FunctionValuesymtabParser &) = delete;
Karl Schimpfc132b762014-09-11 09:43:47 -07002869
2870public:
2871 FunctionValuesymtabParser(unsigned BlockID, FunctionParser *EnclosingParser)
Karl Schimpf58455872014-11-03 11:29:39 -08002872 : ValuesymtabParser(BlockID, EnclosingParser),
2873 Timer(Ice::TimerStack::TT_parseFunctionValuesymtabs,
2874 getTranslator().getContext()) {}
Karl Schimpfc132b762014-09-11 09:43:47 -07002875
2876private:
Karl Schimpf58455872014-11-03 11:29:39 -08002877 Ice::TimerMarker Timer;
Karl Schimpfc132b762014-09-11 09:43:47 -07002878 // Returns the enclosing function parser.
2879 FunctionParser *getFunctionParser() const {
2880 return reinterpret_cast<FunctionParser *>(GetEnclosingParser());
2881 }
2882
Karl Schimpf74cd8832015-06-23 11:05:01 -07002883 void setValueName(NaClBcIndexSize_t Index, StringType &Name) override;
2884 void setBbName(NaClBcIndexSize_t Index, StringType &Name) override;
Karl Schimpfc132b762014-09-11 09:43:47 -07002885
2886 // Reports that the assignment of Name to the value associated with
2887 // index is not possible, for the given Context.
Karl Schimpf74cd8832015-06-23 11:05:01 -07002888 void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index,
Karl Schimpfc132b762014-09-11 09:43:47 -07002889 StringType &Name) {
2890 std::string Buffer;
2891 raw_string_ostream StrBuf(Buffer);
2892 StrBuf << "Function-local " << Context << " name '" << Name
2893 << "' can't be associated with index " << Index;
2894 Error(StrBuf.str());
2895 }
2896};
2897
Karl Schimpf74cd8832015-06-23 11:05:01 -07002898void FunctionValuesymtabParser::setValueName(NaClBcIndexSize_t Index,
2899 StringType &Name) {
Karl Schimpfc132b762014-09-11 09:43:47 -07002900 // Note: We check when Index is too small, so that we can error recover
2901 // (FP->getOperand will create fatal error).
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002902 if (Index < getFunctionParser()->getNumGlobalIDs()) {
Karl Schimpfc132b762014-09-11 09:43:47 -07002903 reportUnableToAssign("instruction", Index, Name);
Karl Schimpfc132b762014-09-11 09:43:47 -07002904 return;
2905 }
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002906 if (isIRGenerationDisabled())
2907 return;
Karl Schimpfc132b762014-09-11 09:43:47 -07002908 Ice::Operand *Op = getFunctionParser()->getOperand(Index);
2909 if (Ice::Variable *V = dyn_cast<Ice::Variable>(Op)) {
Jim Stichnoth20b71f52015-06-24 15:52:24 -07002910 if (Ice::BuildDefs::dump()) {
Jim Stichnoth9a04c072014-12-11 15:51:42 -08002911 std::string Nm(Name.data(), Name.size());
2912 V->setName(getFunctionParser()->getFunc(), Nm);
2913 }
Karl Schimpfc132b762014-09-11 09:43:47 -07002914 } else {
2915 reportUnableToAssign("variable", Index, Name);
2916 }
2917}
2918
Karl Schimpf74cd8832015-06-23 11:05:01 -07002919void FunctionValuesymtabParser::setBbName(NaClBcIndexSize_t Index,
2920 StringType &Name) {
Karl Schimpfac7d7342015-08-06 12:55:23 -07002921 if (!Ice::BuildDefs::dump())
2922 return;
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002923 if (isIRGenerationDisabled())
2924 return;
Karl Schimpf98ed4462015-08-14 13:08:42 -07002925 if (Index >= getFunctionParser()->getFunc()->getNumNodes()) {
2926 reportUnableToAssign("block", Index, Name);
2927 return;
2928 }
Karl Schimpfc132b762014-09-11 09:43:47 -07002929 std::string Nm(Name.data(), Name.size());
Karl Schimpf98ed4462015-08-14 13:08:42 -07002930 if (Ice::BuildDefs::dump())
2931 getFunctionParser()->getFunc()->getNodes()[Index]->setName(Nm);
Karl Schimpfc132b762014-09-11 09:43:47 -07002932}
2933
Karl Schimpff12355e2014-09-08 13:41:09 -07002934bool FunctionParser::ParseBlock(unsigned BlockID) {
2935 switch (BlockID) {
2936 case naclbitc::CONSTANTS_BLOCK_ID: {
2937 ConstantsParser Parser(BlockID, this);
2938 return Parser.ParseThisBlock();
2939 }
Karl Schimpfc132b762014-09-11 09:43:47 -07002940 case naclbitc::VALUE_SYMTAB_BLOCK_ID: {
2941 if (PNaClAllowLocalSymbolTables) {
2942 FunctionValuesymtabParser Parser(BlockID, this);
2943 return Parser.ParseThisBlock();
2944 }
2945 break;
Karl Schimpff12355e2014-09-08 13:41:09 -07002946 }
Karl Schimpfc132b762014-09-11 09:43:47 -07002947 default:
2948 break;
2949 }
2950 return BlockParserBaseClass::ParseBlock(BlockID);
Karl Schimpff12355e2014-09-08 13:41:09 -07002951}
2952
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002953/// Parses the module block in the bitcode file.
2954class ModuleParser : public BlockParserBaseClass {
Jim Stichnothc6ead202015-02-24 09:30:30 -08002955 ModuleParser() = delete;
2956 ModuleParser(const ModuleParser &) = delete;
2957 ModuleParser &operator=(const ModuleParser &) = delete;
2958
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002959public:
2960 ModuleParser(unsigned BlockID, TopLevelParser *Context)
Karl Schimpf6ff33d22014-09-22 10:28:42 -07002961 : BlockParserBaseClass(BlockID, Context),
Karl Schimpf58455872014-11-03 11:29:39 -08002962 Timer(Ice::TimerStack::TT_parseModule,
Jim Stichnotheafb56c2015-06-22 10:35:22 -07002963 Context->getTranslator().getContext()) {}
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002964
Jim Stichnothe587d942015-06-22 15:49:04 -07002965 ~ModuleParser() override = default;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002966
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002967 const char *getBlockName() const override { return "module"; }
2968
Karl Schimpf5ee234a2014-09-12 10:41:40 -07002969private:
Karl Schimpf58455872014-11-03 11:29:39 -08002970 Ice::TimerMarker Timer;
Karl Schimpf9d98d792014-10-13 15:01:08 -07002971 // True if we have already installed names for unnamed global declarations,
2972 // and have generated global constant initializers.
Jim Stichnotheafb56c2015-06-22 10:35:22 -07002973 bool GlobalDeclarationNamesAndInitializersInstalled = false;
Karl Schimpf6ff33d22014-09-22 10:28:42 -07002974
Karl Schimpf9d98d792014-10-13 15:01:08 -07002975 // Generates names for unnamed global addresses (i.e. functions and
2976 // global variables). Then lowers global variable declaration
2977 // initializers to the target. May be called multiple times. Only
2978 // the first call will do the installation.
Karl Schimpf74cd8832015-06-23 11:05:01 -07002979 void installGlobalNamesAndGlobalVarInitializers() {
Karl Schimpf9d98d792014-10-13 15:01:08 -07002980 if (!GlobalDeclarationNamesAndInitializersInstalled) {
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -08002981 Context->installGlobalNames();
2982 Context->createValueIDs();
Jim Stichnothbbca7542015-02-11 16:08:31 -08002983 getTranslator().lowerGlobals(Context->getGlobalVariables());
Karl Schimpf9d98d792014-10-13 15:01:08 -07002984 GlobalDeclarationNamesAndInitializersInstalled = true;
2985 }
2986 }
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07002987 bool ParseBlock(unsigned BlockID) override;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002988
Karl Schimpf74cd8832015-06-23 11:05:01 -07002989 void ExitBlock() override { installGlobalNamesAndGlobalVarInitializers(); }
Karl Schimpf6ff33d22014-09-22 10:28:42 -07002990
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07002991 void ProcessRecord() override;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002992};
2993
Karl Schimpfc132b762014-09-11 09:43:47 -07002994class ModuleValuesymtabParser : public ValuesymtabParser {
Jim Stichnothc6ead202015-02-24 09:30:30 -08002995 ModuleValuesymtabParser() = delete;
Jim Stichnoth0795ba02014-10-01 14:23:01 -07002996 ModuleValuesymtabParser(const ModuleValuesymtabParser &) = delete;
2997 void operator=(const ModuleValuesymtabParser &) = delete;
Karl Schimpfc132b762014-09-11 09:43:47 -07002998
2999public:
3000 ModuleValuesymtabParser(unsigned BlockID, ModuleParser *MP)
Karl Schimpf58455872014-11-03 11:29:39 -08003001 : ValuesymtabParser(BlockID, MP),
3002 Timer(Ice::TimerStack::TT_parseModuleValuesymtabs,
3003 getTranslator().getContext()) {}
Karl Schimpfc132b762014-09-11 09:43:47 -07003004
Jim Stichnothe587d942015-06-22 15:49:04 -07003005 ~ModuleValuesymtabParser() override = default;
Karl Schimpfc132b762014-09-11 09:43:47 -07003006
3007private:
Karl Schimpf58455872014-11-03 11:29:39 -08003008 Ice::TimerMarker Timer;
Karl Schimpf74cd8832015-06-23 11:05:01 -07003009 void setValueName(NaClBcIndexSize_t Index, StringType &Name) override;
3010 void setBbName(NaClBcIndexSize_t Index, StringType &Name) override;
Karl Schimpfc132b762014-09-11 09:43:47 -07003011};
3012
Karl Schimpf74cd8832015-06-23 11:05:01 -07003013void ModuleValuesymtabParser::setValueName(NaClBcIndexSize_t Index,
3014 StringType &Name) {
Karl Schimpf9d98d792014-10-13 15:01:08 -07003015 Context->getGlobalDeclarationByID(Index)
3016 ->setName(StringRef(Name.data(), Name.size()));
Karl Schimpfc132b762014-09-11 09:43:47 -07003017}
3018
Karl Schimpf74cd8832015-06-23 11:05:01 -07003019void ModuleValuesymtabParser::setBbName(NaClBcIndexSize_t Index,
3020 StringType &Name) {
Karl Schimpfc132b762014-09-11 09:43:47 -07003021 std::string Buffer;
3022 raw_string_ostream StrBuf(Buffer);
3023 StrBuf << "Can't define basic block name at global level: '" << Name
3024 << "' -> " << Index;
3025 Error(StrBuf.str());
3026}
3027
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07003028bool ModuleParser::ParseBlock(unsigned BlockID) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003029 switch (BlockID) {
3030 case naclbitc::BLOCKINFO_BLOCK_ID:
3031 return NaClBitcodeParser::ParseBlock(BlockID);
3032 case naclbitc::TYPE_BLOCK_ID_NEW: {
3033 TypesParser Parser(BlockID, this);
3034 return Parser.ParseThisBlock();
3035 }
3036 case naclbitc::GLOBALVAR_BLOCK_ID: {
3037 GlobalsParser Parser(BlockID, this);
3038 return Parser.ParseThisBlock();
3039 }
3040 case naclbitc::VALUE_SYMTAB_BLOCK_ID: {
Karl Schimpfc132b762014-09-11 09:43:47 -07003041 ModuleValuesymtabParser Parser(BlockID, this);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003042 return Parser.ParseThisBlock();
3043 }
3044 case naclbitc::FUNCTION_BLOCK_ID: {
Karl Schimpf74cd8832015-06-23 11:05:01 -07003045 installGlobalNamesAndGlobalVarInitializers();
Karl Schimpfd6064a12014-08-27 15:34:58 -07003046 FunctionParser Parser(BlockID, this);
Jim Stichnoth8e928382015-02-02 17:03:08 -08003047 return Parser.convertFunction();
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003048 }
3049 default:
3050 return BlockParserBaseClass::ParseBlock(BlockID);
3051 }
3052}
3053
3054void ModuleParser::ProcessRecord() {
3055 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
3056 switch (Record.GetCode()) {
3057 case naclbitc::MODULE_CODE_VERSION: {
3058 // VERSION: [version#]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08003059 if (!isValidRecordSize(1, "version"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003060 return;
Karl Schimpf74cd8832015-06-23 11:05:01 -07003061 uint64_t Version = Values[0];
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003062 if (Version != 1) {
3063 std::string Buffer;
3064 raw_string_ostream StrBuf(Buffer);
3065 StrBuf << "Unknown bitstream version: " << Version;
3066 Error(StrBuf.str());
3067 }
3068 return;
3069 }
3070 case naclbitc::MODULE_CODE_FUNCTION: {
3071 // FUNCTION: [type, callingconv, isproto, linkage]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08003072 if (!isValidRecordSize(4, "address"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003073 return;
Karl Schimpf9d98d792014-10-13 15:01:08 -07003074 const Ice::FuncSigType &Signature = Context->getFuncSigTypeByID(Values[0]);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003075 CallingConv::ID CallingConv;
3076 if (!naclbitc::DecodeCallingConv(Values[1], CallingConv)) {
3077 std::string Buffer;
3078 raw_string_ostream StrBuf(Buffer);
Karl Schimpf2f6f8602014-12-01 13:39:00 -08003079 StrBuf << "Function address has unknown calling convention: "
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003080 << Values[1];
3081 Error(StrBuf.str());
3082 return;
3083 }
3084 GlobalValue::LinkageTypes Linkage;
3085 if (!naclbitc::DecodeLinkage(Values[3], Linkage)) {
3086 std::string Buffer;
3087 raw_string_ostream StrBuf(Buffer);
Karl Schimpf2f6f8602014-12-01 13:39:00 -08003088 StrBuf << "Function address has unknown linkage. Found " << Values[3];
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003089 Error(StrBuf.str());
3090 return;
3091 }
Karl Schimpf0c729c82015-01-28 10:58:25 -08003092 bool IsProto = Values[2] == 1;
Karl Schimpf9d98d792014-10-13 15:01:08 -07003093 Ice::FunctionDeclaration *Func = Ice::FunctionDeclaration::create(
John Porto1bec8bc2015-06-22 10:51:13 -07003094 Context->getTranslator().getContext(), Signature, CallingConv, Linkage,
3095 IsProto);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003096 Context->setNextFunctionID(Func);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003097 return;
3098 }
3099 default:
3100 BlockParserBaseClass::ProcessRecord();
3101 return;
3102 }
3103}
3104
3105bool TopLevelParser::ParseBlock(unsigned BlockID) {
3106 if (BlockID == naclbitc::MODULE_BLOCK_ID) {
3107 ModuleParser Parser(BlockID, this);
Karl Schimpfd6064a12014-08-27 15:34:58 -07003108 return Parser.ParseThisBlock();
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003109 }
3110 // Generate error message by using default block implementation.
3111 BlockParserBaseClass Parser(BlockID, this);
3112 return Parser.ParseThisBlock();
3113}
3114
Jim Stichnoth989a7032014-08-08 10:13:44 -07003115} // end of anonymous namespace
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003116
3117namespace Ice {
3118
Karl Schimpf2e7daef2015-01-09 13:04:13 -08003119void PNaClTranslator::translateBuffer(const std::string &IRFilename,
3120 MemoryBuffer *MemBuf) {
Jan Voungc1f07ea2015-03-06 14:53:30 -08003121 std::unique_ptr<MemoryObject> MemObj(getNonStreamedMemoryObject(
3122 reinterpret_cast<const unsigned char *>(MemBuf->getBufferStart()),
3123 reinterpret_cast<const unsigned char *>(MemBuf->getBufferEnd())));
3124 translate(IRFilename, std::move(MemObj));
3125}
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003126
Jan Voungc1f07ea2015-03-06 14:53:30 -08003127void PNaClTranslator::translate(const std::string &IRFilename,
3128 std::unique_ptr<MemoryObject> &&MemObj) {
Jan Voung2f7f2b72015-06-03 17:50:20 -07003129 // On error, we report_fatal_error to avoid destroying the MemObj.
3130 // That may still be in use by IceBrowserCompileServer. Otherwise,
3131 // we need to change the MemObj to be ref-counted, or have a wrapper,
3132 // or simply leak. We also need a hook to tell the IceBrowserCompileServer
3133 // to unblock its QueueStreamer.
3134 // https://code.google.com/p/nativeclient/issues/detail?id=4163
3135 Ostream &ErrStream = getContext()->getStrError();
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003136 // Read header and verify it is good.
3137 NaClBitcodeHeader Header;
Karl Schimpfb33a2af2015-05-12 08:26:23 -07003138 if (Header.Read(MemObj.get())) {
Jan Voung2f7f2b72015-06-03 17:50:20 -07003139 llvm::report_fatal_error("Invalid PNaCl bitcode header");
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003140 }
Karl Schimpfb33a2af2015-05-12 08:26:23 -07003141 if (!Header.IsSupported()) {
Jan Voung2f7f2b72015-06-03 17:50:20 -07003142 ErrStream << Header.Unsupported();
Karl Schimpfb33a2af2015-05-12 08:26:23 -07003143 if (!Header.IsReadable()) {
Jan Voung2f7f2b72015-06-03 17:50:20 -07003144 llvm::report_fatal_error("Invalid PNaCl bitcode header");
Karl Schimpfb33a2af2015-05-12 08:26:23 -07003145 }
3146 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003147
3148 // Create a bitstream reader to read the bitcode file.
Karl Schimpfb33a2af2015-05-12 08:26:23 -07003149 NaClBitstreamReader InputStreamFile(MemObj.release(), Header);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003150 NaClBitstreamCursor InputStream(InputStreamFile);
3151
Karl Schimpf22ed4eb2015-03-04 12:17:20 -08003152 TopLevelParser Parser(*this, InputStream, ErrorStatus);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003153 int TopLevelBlocks = 0;
3154 while (!InputStream.AtEndOfStream()) {
3155 if (Parser.Parse()) {
Jim Stichnothfa4efea2015-01-27 05:06:03 -08003156 ErrorStatus.assign(EC_Bitcode);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003157 return;
3158 }
3159 ++TopLevelBlocks;
3160 }
3161
3162 if (TopLevelBlocks != 1) {
Jan Voung2f7f2b72015-06-03 17:50:20 -07003163 ErrStream << IRFilename
3164 << ": Contains more than one module. Found: " << TopLevelBlocks
3165 << "\n";
3166 llvm::report_fatal_error("Bitcode has more than one module");
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003167 }
Jan Voungc1f07ea2015-03-06 14:53:30 -08003168 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) {
Jan Voung2f7f2b72015-06-03 17:50:20 -07003169 ErrStream
3170 << IRFilename
3171 << ": Bitcode stream should be a multiple of 4 bytes in length.\n";
3172 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes");
Jan Voungc1f07ea2015-03-06 14:53:30 -08003173 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003174}
3175
Jim Stichnoth989a7032014-08-08 10:13:44 -07003176} // end of namespace Ice