blob: 95619a0d064dd9fbd755ecc15280b338edf7111e [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
Jim Stichnoth92a6e5b2015-12-02 16:52:44 -080011/// \brief Implements the interface for translation from PNaCl bitcode files to
12/// ICE to machine code.
Andrew Scull9612d322015-07-06 14:53:25 -070013///
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
Jim Stichnotha18cc9c2014-09-30 19:10:22 -070018#include "IceCfg.h"
19#include "IceCfgNode.h"
20#include "IceClFlags.h"
21#include "IceDefs.h"
Karl Schimpfe3f64d02014-10-07 10:38:22 -070022#include "IceGlobalInits.h"
Jim Stichnotha18cc9c2014-09-30 19:10:22 -070023#include "IceInst.h"
24#include "IceOperand.h"
Jim Stichnothdd6dcfa2016-04-18 12:52:09 -070025#include "IceRangeSpec.h"
Jim Stichnoth98da9662015-06-27 06:38:08 -070026
Jim Stichnothb0051df2016-01-13 11:39:15 -080027#ifdef __clang__
Jim Stichnoth98da9662015-06-27 06:38:08 -070028#pragma clang diagnostic push
29#pragma clang diagnostic ignored "-Wunused-parameter"
Jim Stichnothb0051df2016-01-13 11:39:15 -080030#endif // __clang__
31
Karl Schimpf52863b12015-09-16 13:51:21 -070032#include "llvm/ADT/Hashing.h"
John Porto67f8de92015-06-25 10:14:17 -070033#include "llvm/ADT/SmallString.h"
34#include "llvm/Bitcode/NaCl/NaClBitcodeDecoders.h"
35#include "llvm/Bitcode/NaCl/NaClBitcodeDefs.h"
36#include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h"
37#include "llvm/Bitcode/NaCl/NaClBitcodeParser.h"
38#include "llvm/Bitcode/NaCl/NaClReaderWriter.h"
39#include "llvm/Support/Format.h"
40#include "llvm/Support/MemoryBuffer.h"
41#include "llvm/Support/raw_ostream.h"
Jim Stichnothb0051df2016-01-13 11:39:15 -080042
43#ifdef __clang__
Jim Stichnoth98da9662015-06-27 06:38:08 -070044#pragma clang diagnostic pop
Jim Stichnothb0051df2016-01-13 11:39:15 -080045#endif // __clang__
46
47#include <unordered_set>
Karl Schimpf8d7abae2014-07-07 14:50:30 -070048
Karl Schimpf52863b12015-09-16 13:51:21 -070049// Define a hash function for SmallString's, so that it can be used in hash
50// tables.
51namespace std {
52template <unsigned InternalLen> struct hash<llvm::SmallString<InternalLen>> {
53 size_t operator()(const llvm::SmallString<InternalLen> &Key) const {
54 return llvm::hash_combine_range(Key.begin(), Key.end());
55 }
56};
57} // end of namespace std
58
Karl Schimpf8d7abae2014-07-07 14:50:30 -070059namespace {
Karl Schimpf9d98d792014-10-13 15:01:08 -070060using namespace llvm;
Karl Schimpf8d7abae2014-07-07 14:50:30 -070061
Andrew Scull57e12682015-09-16 11:30:19 -070062// Models elements in the list of types defined in the types block. These
63// elements can be undefined, a (simple) type, or a function type signature.
64// Note that an extended type is undefined on construction. Use methods
65// setAsSimpleType and setAsFuncSigType to define the extended type.
Karl Schimpf645aa1a2014-10-08 09:05:53 -070066class ExtendedType {
Karl Schimpf645aa1a2014-10-08 09:05:53 -070067 ExtendedType &operator=(const ExtendedType &Ty) = delete;
Jim Stichnothdd842db2015-01-27 12:53:53 -080068
Karl Schimpf645aa1a2014-10-08 09:05:53 -070069public:
70 /// Discriminator for LLVM-style RTTI.
71 enum TypeKind { Undefined, Simple, FuncSig };
72
Jim Stichnotheafb56c2015-06-22 10:35:22 -070073 ExtendedType() = default;
Jim Stichnoth7e571362015-01-09 11:43:26 -080074 ExtendedType(const ExtendedType &Ty) = default;
Karl Schimpf645aa1a2014-10-08 09:05:53 -070075
Jim Stichnotheafb56c2015-06-22 10:35:22 -070076 virtual ~ExtendedType() = default;
Karl Schimpf645aa1a2014-10-08 09:05:53 -070077
78 ExtendedType::TypeKind getKind() const { return Kind; }
Karl Schimpfaff9fa22014-10-29 14:32:07 -070079 void dump(Ice::Ostream &Stream) const;
Karl Schimpf645aa1a2014-10-08 09:05:53 -070080
Andrew Scull57e12682015-09-16 11:30:19 -070081 /// Changes the extended type to a simple type with the given / value.
Karl Schimpf645aa1a2014-10-08 09:05:53 -070082 void setAsSimpleType(Ice::Type Ty) {
83 assert(Kind == Undefined);
84 Kind = Simple;
85 Signature.setReturnType(Ty);
86 }
87
88 /// Changes the extended type to an (empty) function signature type.
89 void setAsFunctionType() {
90 assert(Kind == Undefined);
91 Kind = FuncSig;
92 }
93
94protected:
Andrew Scull57e12682015-09-16 11:30:19 -070095 // Note: For simple types, the return type of the signature will be used to
96 // hold the simple type.
Karl Schimpf645aa1a2014-10-08 09:05:53 -070097 Ice::FuncSigType Signature;
98
99private:
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700100 ExtendedType::TypeKind Kind = Undefined;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700101};
102
103Ice::Ostream &operator<<(Ice::Ostream &Stream, const ExtendedType &Ty) {
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700104 if (!Ice::BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800105 return Stream;
Karl Schimpfaff9fa22014-10-29 14:32:07 -0700106 Ty.dump(Stream);
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700107 return Stream;
108}
109
110Ice::Ostream &operator<<(Ice::Ostream &Stream, ExtendedType::TypeKind Kind) {
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700111 if (!Ice::BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800112 return Stream;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700113 Stream << "ExtendedType::";
114 switch (Kind) {
115 case ExtendedType::Undefined:
116 Stream << "Undefined";
117 break;
118 case ExtendedType::Simple:
119 Stream << "Simple";
120 break;
121 case ExtendedType::FuncSig:
122 Stream << "FuncSig";
123 break;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700124 }
125 return Stream;
126}
127
128// Models an ICE type as an extended type.
129class SimpleExtendedType : public ExtendedType {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800130 SimpleExtendedType() = delete;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700131 SimpleExtendedType(const SimpleExtendedType &) = delete;
132 SimpleExtendedType &operator=(const SimpleExtendedType &) = delete;
Jim Stichnothdd842db2015-01-27 12:53:53 -0800133
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700134public:
135 Ice::Type getType() const { return Signature.getReturnType(); }
136
137 static bool classof(const ExtendedType *Ty) {
138 return Ty->getKind() == Simple;
139 }
140};
141
142// Models a function signature as an extended type.
143class FuncSigExtendedType : public ExtendedType {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800144 FuncSigExtendedType() = delete;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700145 FuncSigExtendedType(const FuncSigExtendedType &) = delete;
146 FuncSigExtendedType &operator=(const FuncSigExtendedType &) = delete;
Jim Stichnothdd842db2015-01-27 12:53:53 -0800147
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700148public:
149 const Ice::FuncSigType &getSignature() const { return Signature; }
150 void setReturnType(Ice::Type ReturnType) {
151 Signature.setReturnType(ReturnType);
152 }
153 void appendArgType(Ice::Type ArgType) { Signature.appendArgType(ArgType); }
154 static bool classof(const ExtendedType *Ty) {
155 return Ty->getKind() == FuncSig;
156 }
157};
158
Karl Schimpfaff9fa22014-10-29 14:32:07 -0700159void ExtendedType::dump(Ice::Ostream &Stream) const {
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700160 if (!Ice::BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800161 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700162 Stream << Kind;
163 switch (Kind) {
164 case Simple: {
165 Stream << " " << Signature.getReturnType();
166 break;
167 }
168 case FuncSig: {
169 Stream << " " << Signature;
170 }
171 default:
172 break;
173 }
174}
175
Karl Schimpfa5295b02015-12-01 11:24:53 -0800176// Models integer literals as a sequence of bits. Used to read integer values
177// from bitcode files. Based on llvm::APInt.
178class BitcodeInt {
179 BitcodeInt() = delete;
180 BitcodeInt(const BitcodeInt &) = delete;
181 BitcodeInt &operator=(const BitcodeInt &) = delete;
182
183public:
184 BitcodeInt(Ice::SizeT Bits, uint64_t Val) : BitWidth(Bits), Val(Val) {
185 assert(Bits && "bitwidth too small");
186 assert(Bits <= BITS_PER_WORD && "bitwidth too big");
187 clearUnusedBits();
188 }
189
190 int64_t getSExtValue() const {
191 return static_cast<int64_t>(Val << (BITS_PER_WORD - BitWidth)) >>
192 (BITS_PER_WORD - BitWidth);
193 }
194
195 template <typename IntType, typename FpType>
196 inline FpType convertToFp() const {
197 static_assert(sizeof(IntType) == sizeof(FpType),
198 "IntType and FpType should be the same width");
199 assert(BitWidth == sizeof(IntType) * CHAR_BIT);
200 auto V = static_cast<IntType>(Val);
Jim Stichnothb0051df2016-01-13 11:39:15 -0800201 return Ice::Utils::bitCopy<FpType>(V);
Karl Schimpfa5295b02015-12-01 11:24:53 -0800202 }
203
204private:
205 /// Bits in the (internal) value.
206 static const Ice::SizeT BITS_PER_WORD = sizeof(uint64_t) * CHAR_BIT;
207
208 uint32_t BitWidth; /// The number of bits in the floating point number.
209 uint64_t Val; /// The (64-bit) equivalent integer value.
210
211 /// Clear unused high order bits.
212 void clearUnusedBits() {
213 // If all bits are used, we want to leave the value alone.
214 if (BitWidth == BITS_PER_WORD)
215 return;
216
217 // Mask out the high bits.
218 Val &= ~static_cast<uint64_t>(0) >> (BITS_PER_WORD - BitWidth);
219 }
220};
221
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800222class BlockParserBaseClass;
223
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700224// Top-level class to read PNaCl bitcode files, and translate to ICE.
Karl Schimpfe8457a22016-03-31 10:20:23 -0700225class TopLevelParser final : public NaClBitcodeParser {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800226 TopLevelParser() = delete;
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700227 TopLevelParser(const TopLevelParser &) = delete;
228 TopLevelParser &operator=(const TopLevelParser &) = delete;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700229
230public:
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800231 TopLevelParser(Ice::Translator &Translator, NaClBitstreamCursor &Cursor,
232 Ice::ErrorCode &ErrorStatus)
233 : NaClBitcodeParser(Cursor), Translator(Translator),
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700234 ErrorStatus(ErrorStatus),
235 VariableDeclarations(new Ice::VariableDeclarationList()) {}
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700236
Jim Stichnothe587d942015-06-22 15:49:04 -0700237 ~TopLevelParser() override = default;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700238
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800239 Ice::Translator &getTranslator() const { return Translator; }
Karl Schimpfd6064a12014-08-27 15:34:58 -0700240
Andrew Scull57e12682015-09-16 11:30:19 -0700241 /// Generates error with given Message, occurring at BitPosition within the
242 /// bitcode file. Always returns true.
Karl Schimpf17b1a132015-03-12 09:32:06 -0700243 bool ErrorAt(naclbitc::ErrorLevel Level, uint64_t BitPosition,
Karl Schimpfe8457a22016-03-31 10:20:23 -0700244 const std::string &Message) override;
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800245
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800246 /// Generates error message with respect to the current block parser.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700247 bool blockError(const std::string &Message);
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800248
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700249 /// Changes the size of the type list to the given size.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700250 void resizeTypeIDValues(size_t NewSize) { TypeIDValues.resize(NewSize); }
251
252 size_t getNumTypeIDValues() const { return TypeIDValues.size(); }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700253
John Portoa78e4ba2016-03-15 09:28:04 -0700254 /// Returns a pointer to the pool where globals are allocated.
255 Ice::VariableDeclarationList *getGlobalVariablesPool() {
256 return VariableDeclarations.get();
257 }
258
Andrew Scull57e12682015-09-16 11:30:19 -0700259 /// Returns the undefined type associated with type ID. Note: Returns extended
260 /// type ready to be defined.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700261 ExtendedType *getTypeByIDForDefining(NaClBcIndexSize_t ID) {
Andrew Scull57e12682015-09-16 11:30:19 -0700262 // Get corresponding element, verifying the value is still undefined (and
263 // hence allowed to be defined).
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700264 ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Undefined);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700265 if (Ty)
266 return Ty;
Karl Schimpf74cd8832015-06-23 11:05:01 -0700267 if (ID >= TypeIDValues.size()) {
268 if (ID >= NaClBcIndexSize_t_Max) {
269 std::string Buffer;
270 raw_string_ostream StrBuf(Buffer);
271 StrBuf << "Can't define more than " << NaClBcIndexSize_t_Max
272 << " types\n";
273 blockError(StrBuf.str());
274 // Recover by using existing type slot.
275 return &TypeIDValues[0];
276 }
Jim Stichnoth2f00bf62016-03-11 14:59:43 -0800277 Ice::Utils::reserveAndResize(TypeIDValues, ID + 1);
Karl Schimpf74cd8832015-06-23 11:05:01 -0700278 }
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700279 return &TypeIDValues[ID];
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700280 }
281
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700282 /// Returns the type associated with the given index.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700283 Ice::Type getSimpleTypeByID(NaClBcIndexSize_t ID) {
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700284 const ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Simple);
285 if (Ty == nullptr)
286 // Return error recovery value.
287 return Ice::IceType_void;
288 return cast<SimpleExtendedType>(Ty)->getType();
289 }
290
291 /// Returns the type signature associated with the given index.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700292 const Ice::FuncSigType &getFuncSigTypeByID(NaClBcIndexSize_t ID) {
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700293 const ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::FuncSig);
294 if (Ty == nullptr)
295 // Return error recovery value.
296 return UndefinedFuncSigType;
297 return cast<FuncSigExtendedType>(Ty)->getSignature();
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700298 }
299
300 /// Sets the next function ID to the given LLVM function.
Karl Schimpf9d98d792014-10-13 15:01:08 -0700301 void setNextFunctionID(Ice::FunctionDeclaration *Fcn) {
Karl Schimpf209318a2015-08-20 13:24:02 -0700302 FunctionDeclarations.push_back(Fcn);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700303 }
304
Andrew Scull57e12682015-09-16 11:30:19 -0700305 /// Returns the value id that should be associated with the the current
306 /// function block. Increments internal counters during call so that it will
307 /// be in correct position for next function block.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700308 NaClBcIndexSize_t getNextFunctionBlockValueID() {
Karl Schimpf209318a2015-08-20 13:24:02 -0700309 size_t NumDeclaredFunctions = FunctionDeclarations.size();
Karl Schimpf0c729c82015-01-28 10:58:25 -0800310 while (NextDefiningFunctionID < NumDeclaredFunctions &&
Karl Schimpf209318a2015-08-20 13:24:02 -0700311 FunctionDeclarations[NextDefiningFunctionID]->isProto())
Karl Schimpf0c729c82015-01-28 10:58:25 -0800312 ++NextDefiningFunctionID;
313 if (NextDefiningFunctionID >= NumDeclaredFunctions)
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800314 Fatal("More function blocks than defined function addresses");
Karl Schimpf0c729c82015-01-28 10:58:25 -0800315 return NextDefiningFunctionID++;
Karl Schimpfd6064a12014-08-27 15:34:58 -0700316 }
317
Karl Schimpf9d98d792014-10-13 15:01:08 -0700318 /// Returns the function associated with ID.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700319 Ice::FunctionDeclaration *getFunctionByID(NaClBcIndexSize_t ID) {
Karl Schimpf209318a2015-08-20 13:24:02 -0700320 if (ID < FunctionDeclarations.size())
321 return FunctionDeclarations[ID];
Karl Schimpf9d98d792014-10-13 15:01:08 -0700322 return reportGetFunctionByIDError(ID);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700323 }
324
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800325 /// Returns the constant associated with the given global value ID.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700326 Ice::Constant *getGlobalConstantByID(NaClBcIndexSize_t ID) {
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800327 assert(ID < ValueIDConstants.size());
328 return ValueIDConstants[ID];
Karl Schimpf9d98d792014-10-13 15:01:08 -0700329 }
330
Andrew Scull57e12682015-09-16 11:30:19 -0700331 /// Install names for all global values without names. Called after the global
332 /// value symbol table is processed, but before any function blocks are
333 /// processed.
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800334 void installGlobalNames() {
335 assert(VariableDeclarations);
336 installGlobalVarNames();
337 installFunctionNames();
338 }
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700339
Karl Schimpfbba77682016-01-15 07:33:15 -0800340 void verifyFunctionTypeSignatures();
341
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800342 void createValueIDs() {
343 assert(VariableDeclarations);
344 ValueIDConstants.reserve(VariableDeclarations->size() +
Karl Schimpf209318a2015-08-20 13:24:02 -0700345 FunctionDeclarations.size());
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800346 createValueIDsForFunctions();
347 createValueIDsForGlobalVars();
Karl Schimpf8df26f32014-09-19 09:33:26 -0700348 }
349
Karl Schimpf9d98d792014-10-13 15:01:08 -0700350 /// Returns the number of function declarations in the bitcode file.
Karl Schimpf209318a2015-08-20 13:24:02 -0700351 size_t getNumFunctionIDs() const { return FunctionDeclarations.size(); }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700352
Andrew Scull57e12682015-09-16 11:30:19 -0700353 /// Returns the number of global declarations (i.e. IDs) defined in the
354 /// bitcode file.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700355 size_t getNumGlobalIDs() const {
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800356 if (VariableDeclarations) {
Karl Schimpf209318a2015-08-20 13:24:02 -0700357 return FunctionDeclarations.size() + VariableDeclarations->size();
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800358 } else {
359 return ValueIDConstants.size();
360 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700361 }
362
Karl Schimpfaa0ce792015-08-07 09:28:57 -0700363 /// Adds the given global declaration to the end of the list of global
364 /// declarations.
365 void addGlobalDeclaration(Ice::VariableDeclaration *Decl) {
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800366 assert(VariableDeclarations);
Karl Schimpfaa0ce792015-08-07 09:28:57 -0700367 VariableDeclarations->push_back(Decl);
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700368 }
369
Karl Schimpf9d98d792014-10-13 15:01:08 -0700370 /// Returns the global variable declaration with the given index.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700371 Ice::VariableDeclaration *getGlobalVariableByID(NaClBcIndexSize_t Index) {
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800372 assert(VariableDeclarations);
373 if (Index < VariableDeclarations->size())
374 return VariableDeclarations->at(Index);
Karl Schimpf9d98d792014-10-13 15:01:08 -0700375 return reportGetGlobalVariableByIDError(Index);
376 }
377
Andrew Scull57e12682015-09-16 11:30:19 -0700378 /// Returns the global declaration (variable or function) with the given
379 /// Index.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700380 Ice::GlobalDeclaration *getGlobalDeclarationByID(NaClBcIndexSize_t Index) {
Karl Schimpf209318a2015-08-20 13:24:02 -0700381 size_t NumFunctionIds = FunctionDeclarations.size();
Karl Schimpf9d98d792014-10-13 15:01:08 -0700382 if (Index < NumFunctionIds)
383 return getFunctionByID(Index);
384 else
385 return getGlobalVariableByID(Index - NumFunctionIds);
386 }
387
Karl Schimpf0b8763e2015-09-22 10:41:11 -0700388 /// Returns true if a module block has been parsed.
389 bool parsedModuleBlock() const { return ParsedModuleBlock; }
390
Andrew Scull57e12682015-09-16 11:30:19 -0700391 /// Returns the list of parsed global variable declarations. Releases
392 /// ownership of the current list of global variables. Note: only returns
393 /// non-null pointer on first call. All successive calls return a null
394 /// pointer.
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800395 std::unique_ptr<Ice::VariableDeclarationList> getGlobalVariables() {
Andrew Scull57e12682015-09-16 11:30:19 -0700396 // Before returning, check that ValidIDConstants has already been built.
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800397 assert(!VariableDeclarations ||
398 VariableDeclarations->size() <= ValueIDConstants.size());
399 return std::move(VariableDeclarations);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700400 }
401
Karl Schimpf07af2ac2015-09-30 15:33:41 -0700402 // Upper limit of alignment power allowed by LLVM
403 static constexpr uint32_t AlignPowerLimit = 29;
404
405 // Extracts the corresponding Alignment to use, given the AlignPower (i.e.
406 // 2**(AlignPower-1), or 0 if AlignPower == 0). Parser defines the block
407 // context the alignment check appears in, and Prefix defines the context the
408 // alignment appears in.
409 uint32_t extractAlignment(NaClBitcodeParser *Parser, const char *Prefix,
410 uint32_t AlignPower) {
411 if (AlignPower <= AlignPowerLimit + 1)
412 return (1 << AlignPower) >> 1;
413 std::string Buffer;
414 raw_string_ostream StrBuf(Buffer);
415 StrBuf << Prefix << " alignment greater than 2**" << AlignPowerLimit
416 << ". Found: 2**" << (AlignPower - 1);
417 Parser->Error(StrBuf.str());
418 // Error recover with value that is always acceptable.
419 return 1;
420 }
421
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700422private:
Karl Schimpfd6064a12014-08-27 15:34:58 -0700423 // The translator associated with the parser.
424 Ice::Translator &Translator;
Karl Schimpfe8457a22016-03-31 10:20:23 -0700425
426 // ErrorStatus should only be updated while this lock is locked.
427 Ice::GlobalLockType ErrorReportingLock;
Karl Schimpfb164d202014-07-11 10:26:34 -0700428 // The exit status that should be set to true if an error occurs.
Jim Stichnothfa4efea2015-01-27 05:06:03 -0800429 Ice::ErrorCode &ErrorStatus;
Karl Schimpfe8457a22016-03-31 10:20:23 -0700430
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700431 // The types associated with each type ID.
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700432 std::vector<ExtendedType> TypeIDValues;
Karl Schimpf0c729c82015-01-28 10:58:25 -0800433 // The set of functions (prototype and defined).
Karl Schimpf209318a2015-08-20 13:24:02 -0700434 Ice::FunctionDeclarationList FunctionDeclarations;
435 // The ID of the next possible defined function ID in FunctionDeclarations.
436 // FunctionDeclarations is filled first. It's the set of functions (either
437 // defined or isproto). Then function definitions are encountered/parsed and
438 // NextDefiningFunctionID is incremented to track the next actually-defined
439 // function.
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700440 size_t NextDefiningFunctionID = 0;
Karl Schimpf9d98d792014-10-13 15:01:08 -0700441 // The set of global variables.
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800442 std::unique_ptr<Ice::VariableDeclarationList> VariableDeclarations;
Karl Schimpf9d98d792014-10-13 15:01:08 -0700443 // Relocatable constants associated with global declarations.
Karl Schimpf209318a2015-08-20 13:24:02 -0700444 Ice::ConstantList ValueIDConstants;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700445 // Error recovery value to use when getFuncSigTypeByID fails.
446 Ice::FuncSigType UndefinedFuncSigType;
Karl Schimpf0b8763e2015-09-22 10:41:11 -0700447 // Defines if a module block has already been parsed.
448 bool ParsedModuleBlock = false;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700449
Jim Stichnoth8e8042c2014-09-25 17:51:47 -0700450 bool ParseBlock(unsigned BlockID) override;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700451
Andrew Scull57e12682015-09-16 11:30:19 -0700452 // Gets extended type associated with the given index, assuming the extended
453 // type is of the WantedKind. Generates error message if corresponding
454 // extended type of WantedKind can't be found, and returns nullptr.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700455 ExtendedType *getTypeByIDAsKind(NaClBcIndexSize_t ID,
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700456 ExtendedType::TypeKind WantedKind) {
457 ExtendedType *Ty = nullptr;
458 if (ID < TypeIDValues.size()) {
459 Ty = &TypeIDValues[ID];
460 if (Ty->getKind() == WantedKind)
461 return Ty;
462 }
463 // Generate an error message and set ErrorStatus.
464 this->reportBadTypeIDAs(ID, Ty, WantedKind);
465 return nullptr;
466 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700467
Andrew Scull57e12682015-09-16 11:30:19 -0700468 // Gives Decl a name if it doesn't already have one. Prefix and NameIndex are
469 // used to generate the name. NameIndex is automatically incremented if a new
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700470 // name is created. DeclType is literal text describing the type of name being
471 // created. Also generates a warning if created names may conflict with named
472 // declarations.
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800473 void installDeclarationName(Ice::GlobalDeclaration *Decl,
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700474 const std::string &Prefix, const char *DeclType,
Karl Schimpf74cd8832015-06-23 11:05:01 -0700475 NaClBcIndexSize_t &NameIndex) {
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800476 if (Decl->hasName()) {
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700477 Translator.checkIfUnnamedNameSafe(Decl->getName().toString(), DeclType,
478 Prefix);
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800479 } else {
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700480 Ice::GlobalContext *Ctx = Translator.getContext();
Jim Stichnoth318c01b2016-04-03 21:58:03 -0700481 // Synthesize a dummy name if any of the following is true:
482 // - DUMP is enabled
483 // - The symbol is external
484 // - The -timing-funcs flag is enabled
Jim Stichnothdd6dcfa2016-04-18 12:52:09 -0700485 // - Some RangeSpec is initialized with actual names
Jim Stichnoth318c01b2016-04-03 21:58:03 -0700486 if (Ice::BuildDefs::dump() || !Decl->isInternal() ||
Jim Stichnothdd6dcfa2016-04-18 12:52:09 -0700487 Ice::RangeSpec::hasNames() || Ice::getFlags().getTimeEachFunction()) {
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700488 Decl->setName(Ctx, Translator.createUnnamedName(Prefix, NameIndex));
489 } else {
490 Decl->setName(Ctx);
491 }
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800492 ++NameIndex;
493 }
494 }
495
496 // Installs names for global variables without names.
497 void installGlobalVarNames() {
498 assert(VariableDeclarations);
Karl Schimpfd4699942016-04-02 09:55:31 -0700499 const std::string &GlobalPrefix = Ice::getFlags().getDefaultGlobalPrefix();
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800500 if (!GlobalPrefix.empty()) {
Karl Schimpf74cd8832015-06-23 11:05:01 -0700501 NaClBcIndexSize_t NameIndex = 0;
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800502 for (Ice::VariableDeclaration *Var : *VariableDeclarations) {
503 installDeclarationName(Var, GlobalPrefix, "global", NameIndex);
504 }
505 }
506 }
507
508 // Installs names for functions without names.
509 void installFunctionNames() {
Karl Schimpfd4699942016-04-02 09:55:31 -0700510 const std::string &FunctionPrefix =
511 Ice::getFlags().getDefaultFunctionPrefix();
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800512 if (!FunctionPrefix.empty()) {
Karl Schimpf74cd8832015-06-23 11:05:01 -0700513 NaClBcIndexSize_t NameIndex = 0;
Karl Schimpf209318a2015-08-20 13:24:02 -0700514 for (Ice::FunctionDeclaration *Func : FunctionDeclarations) {
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800515 installDeclarationName(Func, FunctionPrefix, "function", NameIndex);
516 }
517 }
518 }
519
Jim Stichnoth98ba0062016-03-07 09:26:22 -0800520 // Builds a constant symbol named Name. IsExternal is true iff the symbol is
521 // external.
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700522 Ice::Constant *getConstantSym(Ice::GlobalString Name, bool IsExternal) const {
523 Ice::GlobalContext *Ctx = getTranslator().getContext();
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800524 if (IsExternal) {
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700525 return Ctx->getConstantExternSym(Name);
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800526 } else {
527 const Ice::RelocOffsetT Offset = 0;
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700528 return Ctx->getConstantSym(Offset, Name);
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800529 }
530 }
531
Karl Schimpfa313a122015-10-08 10:40:57 -0700532 void reportLinkageError(const char *Kind,
533 const Ice::GlobalDeclaration &Decl) {
534 std::string Buffer;
535 raw_string_ostream StrBuf(Buffer);
536 StrBuf << Kind << " " << Decl.getName()
537 << " has incorrect linkage: " << Decl.getLinkageName();
538 if (Decl.isExternal())
539 StrBuf << "\n Use flag -allow-externally-defined-symbols to override";
540 Error(StrBuf.str());
541 }
542
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800543 // Converts function declarations into constant value IDs.
544 void createValueIDsForFunctions() {
Karl Schimpf57d31ac2015-10-07 09:53:12 -0700545 Ice::GlobalContext *Ctx = getTranslator().getContext();
Karl Schimpf209318a2015-08-20 13:24:02 -0700546 for (const Ice::FunctionDeclaration *Func : FunctionDeclarations) {
Karl Schimpfa313a122015-10-08 10:40:57 -0700547 if (!Func->verifyLinkageCorrect(Ctx))
548 reportLinkageError("Function", *Func);
Jim Stichnoth98ba0062016-03-07 09:26:22 -0800549 Ice::Constant *C = getConstantSym(Func->getName(), Func->isProto());
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800550 ValueIDConstants.push_back(C);
551 }
552 }
553
554 // Converts global variable declarations into constant value IDs.
555 void createValueIDsForGlobalVars() {
556 for (const Ice::VariableDeclaration *Decl : *VariableDeclarations) {
Karl Schimpfd4699942016-04-02 09:55:31 -0700557 if (!Decl->verifyLinkageCorrect())
Karl Schimpfa313a122015-10-08 10:40:57 -0700558 reportLinkageError("Global", *Decl);
Jim Stichnoth0d4fc922015-12-13 21:36:33 -0800559 Ice::Constant *C =
Jim Stichnoth98ba0062016-03-07 09:26:22 -0800560 getConstantSym(Decl->getName(), !Decl->hasInitializer());
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800561 ValueIDConstants.push_back(C);
562 }
563 }
564
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700565 // Reports that type ID is undefined, or not of the WantedType.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700566 void reportBadTypeIDAs(NaClBcIndexSize_t ID, const ExtendedType *Ty,
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700567 ExtendedType::TypeKind WantedType);
Karl Schimpfd6064a12014-08-27 15:34:58 -0700568
Andrew Scull57e12682015-09-16 11:30:19 -0700569 // Reports that there is no function declaration for ID. Returns an error
570 // recovery value to use.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700571 Ice::FunctionDeclaration *reportGetFunctionByIDError(NaClBcIndexSize_t ID);
Karl Schimpf9d98d792014-10-13 15:01:08 -0700572
Andrew Scull57e12682015-09-16 11:30:19 -0700573 // Reports that there is not global variable declaration for ID. Returns an
574 // error recovery value to use.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700575 Ice::VariableDeclaration *
576 reportGetGlobalVariableByIDError(NaClBcIndexSize_t Index);
Karl Schimpf9d98d792014-10-13 15:01:08 -0700577
Andrew Scull57e12682015-09-16 11:30:19 -0700578 // Reports that there is no corresponding ICE type for LLVMTy, and returns
579 // Ice::IceType_void.
Karl Schimpfd6064a12014-08-27 15:34:58 -0700580 Ice::Type convertToIceTypeError(Type *LLVMTy);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700581};
582
Karl Schimpf17b1a132015-03-12 09:32:06 -0700583bool TopLevelParser::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit,
584 const std::string &Message) {
Karl Schimpf819d7b52015-01-22 10:00:07 -0800585 Ice::GlobalContext *Context = Translator.getContext();
Karl Schimpfe8457a22016-03-31 10:20:23 -0700586 {
587 std::unique_lock<Ice::GlobalLockType> _(ErrorReportingLock);
588 ErrorStatus.assign(Ice::EC_Bitcode);
589 }
Karl Schimpfd8b32892015-04-16 15:47:25 -0700590 { // Lock while printing out error message.
591 Ice::OstreamLocker L(Context);
Karl Schimpf2f67b922015-04-22 15:20:16 -0700592 raw_ostream &OldErrStream = setErrStream(Context->getStrError());
Karl Schimpfd8b32892015-04-16 15:47:25 -0700593 NaClBitcodeParser::ErrorAt(Level, Bit, Message);
594 setErrStream(OldErrStream);
595 }
Karl Schimpfd4699942016-04-02 09:55:31 -0700596 if (Level >= naclbitc::Error && !Ice::getFlags().getAllowErrorRecovery())
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800597 Fatal();
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800598 return true;
599}
600
Karl Schimpf74cd8832015-06-23 11:05:01 -0700601void TopLevelParser::reportBadTypeIDAs(NaClBcIndexSize_t ID,
602 const ExtendedType *Ty,
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700603 ExtendedType::TypeKind WantedType) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700604 std::string Buffer;
605 raw_string_ostream StrBuf(Buffer);
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700606 if (Ty == nullptr) {
607 StrBuf << "Can't find extended type for type id: " << ID;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700608 } else {
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700609 StrBuf << "Type id " << ID << " not " << WantedType << ". Found: " << *Ty;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700610 }
Karl Schimpf74cd8832015-06-23 11:05:01 -0700611 blockError(StrBuf.str());
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700612}
613
Karl Schimpf9d98d792014-10-13 15:01:08 -0700614Ice::FunctionDeclaration *
Karl Schimpf74cd8832015-06-23 11:05:01 -0700615TopLevelParser::reportGetFunctionByIDError(NaClBcIndexSize_t ID) {
Karl Schimpf9d98d792014-10-13 15:01:08 -0700616 std::string Buffer;
617 raw_string_ostream StrBuf(Buffer);
618 StrBuf << "Function index " << ID
619 << " not allowed. Out of range. Must be less than "
Karl Schimpf209318a2015-08-20 13:24:02 -0700620 << FunctionDeclarations.size();
Karl Schimpf74cd8832015-06-23 11:05:01 -0700621 blockError(StrBuf.str());
Karl Schimpf209318a2015-08-20 13:24:02 -0700622 if (!FunctionDeclarations.empty())
623 return FunctionDeclarations[0];
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800624 Fatal();
Karl Schimpf9d98d792014-10-13 15:01:08 -0700625}
626
627Ice::VariableDeclaration *
Karl Schimpf74cd8832015-06-23 11:05:01 -0700628TopLevelParser::reportGetGlobalVariableByIDError(NaClBcIndexSize_t Index) {
Karl Schimpf9d98d792014-10-13 15:01:08 -0700629 std::string Buffer;
630 raw_string_ostream StrBuf(Buffer);
631 StrBuf << "Global index " << Index
632 << " not allowed. Out of range. Must be less than "
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800633 << VariableDeclarations->size();
Karl Schimpf74cd8832015-06-23 11:05:01 -0700634 blockError(StrBuf.str());
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800635 if (!VariableDeclarations->empty())
636 return VariableDeclarations->at(0);
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800637 Fatal();
Karl Schimpf9d98d792014-10-13 15:01:08 -0700638}
639
Karl Schimpfd6064a12014-08-27 15:34:58 -0700640Ice::Type TopLevelParser::convertToIceTypeError(Type *LLVMTy) {
641 std::string Buffer;
642 raw_string_ostream StrBuf(Buffer);
643 StrBuf << "Invalid LLVM type: " << *LLVMTy;
644 Error(StrBuf.str());
645 return Ice::IceType_void;
646}
647
Karl Schimpfbba77682016-01-15 07:33:15 -0800648void TopLevelParser::verifyFunctionTypeSignatures() {
649 const Ice::GlobalContext *Ctx = getTranslator().getContext();
650 for (Ice::FunctionDeclaration *FuncDecl : FunctionDeclarations) {
651 if (!FuncDecl->validateTypeSignature(Ctx))
652 Error(FuncDecl->getTypeSignatureError(Ctx));
653 }
654}
655
Andrew Scull57e12682015-09-16 11:30:19 -0700656// Base class for parsing blocks within the bitcode file. Note: Because this is
657// the base class of block parsers, we generate error messages if ParseBlock or
658// ParseRecord is not overridden in derived classes.
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700659class BlockParserBaseClass : public NaClBitcodeParser {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800660 BlockParserBaseClass() = delete;
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800661 BlockParserBaseClass(const BlockParserBaseClass &) = delete;
662 BlockParserBaseClass &operator=(const BlockParserBaseClass &) = delete;
663
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700664public:
665 // Constructor for the top-level module block parser.
666 BlockParserBaseClass(unsigned BlockID, TopLevelParser *Context)
Karl Schimpfe8457a22016-03-31 10:20:23 -0700667 : NaClBitcodeParser(BlockID, Context), Context(Context) {}
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700668
Karl Schimpfe8457a22016-03-31 10:20:23 -0700669 BlockParserBaseClass(unsigned BlockID, BlockParserBaseClass *EnclosingParser,
670 NaClBitstreamCursor &Cursor)
671 : NaClBitcodeParser(BlockID, EnclosingParser, Cursor),
672 Context(EnclosingParser->Context) {}
673
674 ~BlockParserBaseClass() override {}
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800675
676 // Returns the printable name of the type of block being parsed.
677 virtual const char *getBlockName() const {
678 // If this class is used, it is parsing an unknown block.
679 return "unknown";
680 }
681
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800682 // Generates an error Message with the Bit address prefixed to it.
Karl Schimpf17b1a132015-03-12 09:32:06 -0700683 bool ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit,
Karl Schimpfe8457a22016-03-31 10:20:23 -0700684 const std::string &Message) override;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700685
686protected:
687 // The context parser that contains the decoded state.
688 TopLevelParser *Context;
Karl Schimpfe8457a22016-03-31 10:20:23 -0700689 // True if ErrorAt has been called in this block.
690 bool BlockHasError = false;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700691
692 // Constructor for nested block parsers.
693 BlockParserBaseClass(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
694 : NaClBitcodeParser(BlockID, EnclosingParser),
695 Context(EnclosingParser->Context) {}
696
Karl Schimpfd6064a12014-08-27 15:34:58 -0700697 // Gets the translator associated with the bitcode parser.
Karl Schimpf6ff33d22014-09-22 10:28:42 -0700698 Ice::Translator &getTranslator() const { return Context->getTranslator(); }
699
Andrew Scull57e12682015-09-16 11:30:19 -0700700 // Default implementation. Reports that block is unknown and skips its
701 // contents.
Jim Stichnoth8e8042c2014-09-25 17:51:47 -0700702 bool ParseBlock(unsigned BlockID) override;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700703
Andrew Scull57e12682015-09-16 11:30:19 -0700704 // Default implementation. Reports that the record is not understood.
Jim Stichnoth8e8042c2014-09-25 17:51:47 -0700705 void ProcessRecord() override;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700706
Andrew Scull57e12682015-09-16 11:30:19 -0700707 // Checks if the size of the record is Size. Return true if valid. Otherwise
708 // generates an error and returns false.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700709 bool isValidRecordSize(size_t Size, const char *RecordName) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700710 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
Karl Schimpfd6064a12014-08-27 15:34:58 -0700711 if (Values.size() == Size)
712 return true;
Karl Schimpf74cd8832015-06-23 11:05:01 -0700713 reportRecordSizeError(Size, RecordName, nullptr);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700714 return false;
715 }
716
Andrew Scull57e12682015-09-16 11:30:19 -0700717 // Checks if the size of the record is at least as large as the LowerLimit.
718 // Returns true if valid. Otherwise generates an error and returns false.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700719 bool isValidRecordSizeAtLeast(size_t LowerLimit, const char *RecordName) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700720 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
Karl Schimpfd6064a12014-08-27 15:34:58 -0700721 if (Values.size() >= LowerLimit)
722 return true;
Karl Schimpf74cd8832015-06-23 11:05:01 -0700723 reportRecordSizeError(LowerLimit, RecordName, "at least");
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700724 return false;
725 }
726
Karl Schimpfd6064a12014-08-27 15:34:58 -0700727 // Checks if the size of the record is no larger than the
Andrew Scull57e12682015-09-16 11:30:19 -0700728 // UpperLimit. Returns true if valid. Otherwise generates an error and
729 // returns false.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700730 bool isValidRecordSizeAtMost(size_t UpperLimit, const char *RecordName) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700731 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
Karl Schimpfd6064a12014-08-27 15:34:58 -0700732 if (Values.size() <= UpperLimit)
733 return true;
Karl Schimpf74cd8832015-06-23 11:05:01 -0700734 reportRecordSizeError(UpperLimit, RecordName, "no more than");
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700735 return false;
736 }
737
Andrew Scull57e12682015-09-16 11:30:19 -0700738 // Checks if the size of the record is at least as large as the LowerLimit,
739 // and no larger than the UpperLimit. Returns true if valid. Otherwise
740 // generates an error and returns false.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700741 bool isValidRecordSizeInRange(size_t LowerLimit, size_t UpperLimit,
Karl Schimpfd6064a12014-08-27 15:34:58 -0700742 const char *RecordName) {
743 return isValidRecordSizeAtLeast(LowerLimit, RecordName) ||
744 isValidRecordSizeAtMost(UpperLimit, RecordName);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700745 }
746
747private:
Andrew Scull57e12682015-09-16 11:30:19 -0700748 /// Generates a record size error. ExpectedSize is the number of elements
749 /// expected. RecordName is the name of the kind of record that has incorrect
750 /// size. ContextMessage (if not nullptr) is appended to "record expects" to
751 /// describe how ExpectedSize should be interpreted.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700752 void reportRecordSizeError(size_t ExpectedSize, const char *RecordName,
Karl Schimpfd6064a12014-08-27 15:34:58 -0700753 const char *ContextMessage);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700754};
755
Karl Schimpf74cd8832015-06-23 11:05:01 -0700756bool TopLevelParser::blockError(const std::string &Message) {
Karl Schimpfe8457a22016-03-31 10:20:23 -0700757 // TODO(kschimpf): Remove this method. This method used to redirect
758 // block-level errors to the block we are in, rather than the top-level
759 // block. This gave better bit location for error messages. However, with
760 // parallel parsing, we can't keep a field to redirect (there could be many
761 // and we don't know which block parser applies). Hence, This redirect can't
762 // be applied anymore.
763 return Error(Message);
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800764}
765
766// Generates an error Message with the bit address prefixed to it.
Jan Voungf644a4b2015-03-19 11:57:52 -0700767bool BlockParserBaseClass::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit,
768 const std::string &Message) {
Karl Schimpfe8457a22016-03-31 10:20:23 -0700769 BlockHasError = true;
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800770 std::string Buffer;
771 raw_string_ostream StrBuf(Buffer);
Andrew Scull57e12682015-09-16 11:30:19 -0700772 // Note: If dump routines have been turned off, the error messages will not
773 // be readable. Hence, replace with simple error. We also use the simple form
774 // for unit tests.
Karl Schimpfd4699942016-04-02 09:55:31 -0700775 if (Ice::getFlags().getGenerateUnitTestMessages()) {
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800776 StrBuf << "Invalid " << getBlockName() << " record: <" << Record.GetCode();
777 for (const uint64_t Val : Record.GetValues()) {
778 StrBuf << " " << Val;
779 }
780 StrBuf << ">";
Karl Schimpfdf80eb82015-02-09 14:20:22 -0800781 } else {
782 StrBuf << Message;
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800783 }
Karl Schimpf2a9d1862016-04-02 10:06:56 -0700784 return Context->ErrorAt(Level, Record.GetCursor().getErrorBitNo(Bit),
785 StrBuf.str());
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800786}
787
Karl Schimpf74cd8832015-06-23 11:05:01 -0700788void BlockParserBaseClass::reportRecordSizeError(size_t ExpectedSize,
Karl Schimpfd6064a12014-08-27 15:34:58 -0700789 const char *RecordName,
790 const char *ContextMessage) {
791 std::string Buffer;
792 raw_string_ostream StrBuf(Buffer);
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800793 const char *BlockName = getBlockName();
794 const char FirstChar = toupper(*BlockName);
795 StrBuf << FirstChar << (BlockName + 1) << " " << RecordName
796 << " record expects";
Karl Schimpfd6064a12014-08-27 15:34:58 -0700797 if (ContextMessage)
798 StrBuf << " " << ContextMessage;
799 StrBuf << " " << ExpectedSize << " argument";
800 if (ExpectedSize > 1)
801 StrBuf << "s";
802 StrBuf << ". Found: " << Record.GetValues().size();
803 Error(StrBuf.str());
804}
805
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700806bool BlockParserBaseClass::ParseBlock(unsigned BlockID) {
Andrew Scull57e12682015-09-16 11:30:19 -0700807 // If called, derived class doesn't know how to handle block. Report error
808 // and skip.
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700809 std::string Buffer;
810 raw_string_ostream StrBuf(Buffer);
811 StrBuf << "Don't know how to parse block id: " << BlockID;
812 Error(StrBuf.str());
813 SkipBlock();
814 return false;
815}
816
817void BlockParserBaseClass::ProcessRecord() {
818 // If called, derived class doesn't know how to handle.
819 std::string Buffer;
820 raw_string_ostream StrBuf(Buffer);
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800821 StrBuf << "Don't know how to process " << getBlockName()
822 << " record:" << Record;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700823 Error(StrBuf.str());
824}
825
826// Class to parse a types block.
Karl Schimpfe8457a22016-03-31 10:20:23 -0700827class TypesParser final : public BlockParserBaseClass {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800828 TypesParser() = delete;
829 TypesParser(const TypesParser &) = delete;
830 TypesParser &operator=(const TypesParser &) = delete;
831
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700832public:
833 TypesParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
Karl Schimpf58455872014-11-03 11:29:39 -0800834 : BlockParserBaseClass(BlockID, EnclosingParser),
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700835 Timer(Ice::TimerStack::TT_parseTypes, getTranslator().getContext()) {}
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700836
Karl Schimpf74cd8832015-06-23 11:05:01 -0700837 ~TypesParser() override {
838 if (ExpectedNumTypes != Context->getNumTypeIDValues()) {
839 std::string Buffer;
840 raw_string_ostream StrBuf(Buffer);
841 StrBuf << "Types block expected " << ExpectedNumTypes
842 << " types but found: " << NextTypeId;
843 Error(StrBuf.str());
844 }
845 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700846
847private:
Karl Schimpf58455872014-11-03 11:29:39 -0800848 Ice::TimerMarker Timer;
Andrew Scull57e12682015-09-16 11:30:19 -0700849 // The type ID that will be associated with the next type defining record in
850 // the types block.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700851 NaClBcIndexSize_t NextTypeId = 0;
852
853 // The expected number of types, based on record TYPE_CODE_NUMENTRY.
854 NaClBcIndexSize_t ExpectedNumTypes = 0;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700855
Jim Stichnoth8e8042c2014-09-25 17:51:47 -0700856 void ProcessRecord() override;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700857
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800858 const char *getBlockName() const override { return "type"; }
859
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700860 void setNextTypeIDAsSimpleType(Ice::Type Ty) {
861 Context->getTypeByIDForDefining(NextTypeId++)->setAsSimpleType(Ty);
862 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700863};
864
865void TypesParser::ProcessRecord() {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700866 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
867 switch (Record.GetCode()) {
Karl Schimpf74cd8832015-06-23 11:05:01 -0700868 case naclbitc::TYPE_CODE_NUMENTRY: {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700869 // NUMENTRY: [numentries]
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800870 if (!isValidRecordSize(1, "count"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700871 return;
Karl Schimpf74cd8832015-06-23 11:05:01 -0700872 uint64_t Size = Values[0];
873 if (Size > NaClBcIndexSize_t_Max) {
874 std::string Buffer;
875 raw_string_ostream StrBuf(Buffer);
876 StrBuf << "Size to big for count record: " << Size;
877 Error(StrBuf.str());
878 ExpectedNumTypes = NaClBcIndexSize_t_Max;
879 }
Andrew Scull57e12682015-09-16 11:30:19 -0700880 // The code double checks that Expected size and the actual size at the end
881 // of the block. To reduce allocations we preallocate the space.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700882 //
Andrew Scull57e12682015-09-16 11:30:19 -0700883 // However, if the number is large, we suspect that the number is
884 // (possibly) incorrect. In that case, we preallocate a smaller space.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700885 constexpr uint64_t DefaultLargeResizeValue = 1000000;
886 Context->resizeTypeIDValues(std::min(Size, DefaultLargeResizeValue));
887 ExpectedNumTypes = Size;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700888 return;
Karl Schimpf74cd8832015-06-23 11:05:01 -0700889 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700890 case naclbitc::TYPE_CODE_VOID:
891 // VOID
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800892 if (!isValidRecordSize(0, "void"))
Karl Schimpfd6064a12014-08-27 15:34:58 -0700893 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700894 setNextTypeIDAsSimpleType(Ice::IceType_void);
895 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700896 case naclbitc::TYPE_CODE_FLOAT:
897 // FLOAT
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800898 if (!isValidRecordSize(0, "float"))
Karl Schimpfd6064a12014-08-27 15:34:58 -0700899 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700900 setNextTypeIDAsSimpleType(Ice::IceType_f32);
901 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700902 case naclbitc::TYPE_CODE_DOUBLE:
903 // DOUBLE
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800904 if (!isValidRecordSize(0, "double"))
Karl Schimpfd6064a12014-08-27 15:34:58 -0700905 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700906 setNextTypeIDAsSimpleType(Ice::IceType_f64);
907 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700908 case naclbitc::TYPE_CODE_INTEGER:
909 // INTEGER: [width]
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800910 if (!isValidRecordSize(1, "integer"))
Karl Schimpfd6064a12014-08-27 15:34:58 -0700911 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700912 switch (Values[0]) {
913 case 1:
914 setNextTypeIDAsSimpleType(Ice::IceType_i1);
915 return;
916 case 8:
917 setNextTypeIDAsSimpleType(Ice::IceType_i8);
918 return;
919 case 16:
920 setNextTypeIDAsSimpleType(Ice::IceType_i16);
921 return;
922 case 32:
923 setNextTypeIDAsSimpleType(Ice::IceType_i32);
924 return;
925 case 64:
926 setNextTypeIDAsSimpleType(Ice::IceType_i64);
927 return;
928 default:
929 break;
930 }
931 {
Karl Schimpfd6064a12014-08-27 15:34:58 -0700932 std::string Buffer;
933 raw_string_ostream StrBuf(Buffer);
934 StrBuf << "Type integer record with invalid bitsize: " << Values[0];
935 Error(StrBuf.str());
Karl Schimpfd6064a12014-08-27 15:34:58 -0700936 }
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700937 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -0700938 case naclbitc::TYPE_CODE_VECTOR: {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700939 // VECTOR: [numelts, eltty]
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800940 if (!isValidRecordSize(2, "vector"))
Karl Schimpfd6064a12014-08-27 15:34:58 -0700941 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700942 Ice::Type BaseTy = Context->getSimpleTypeByID(Values[1]);
943 Ice::SizeT Size = Values[0];
944 switch (BaseTy) {
945 case Ice::IceType_i1:
946 switch (Size) {
947 case 4:
948 setNextTypeIDAsSimpleType(Ice::IceType_v4i1);
949 return;
950 case 8:
951 setNextTypeIDAsSimpleType(Ice::IceType_v8i1);
952 return;
953 case 16:
954 setNextTypeIDAsSimpleType(Ice::IceType_v16i1);
955 return;
956 default:
957 break;
958 }
959 break;
960 case Ice::IceType_i8:
961 if (Size == 16) {
962 setNextTypeIDAsSimpleType(Ice::IceType_v16i8);
963 return;
964 }
965 break;
966 case Ice::IceType_i16:
967 if (Size == 8) {
968 setNextTypeIDAsSimpleType(Ice::IceType_v8i16);
969 return;
970 }
971 break;
972 case Ice::IceType_i32:
973 if (Size == 4) {
974 setNextTypeIDAsSimpleType(Ice::IceType_v4i32);
975 return;
976 }
977 break;
978 case Ice::IceType_f32:
979 if (Size == 4) {
980 setNextTypeIDAsSimpleType(Ice::IceType_v4f32);
981 return;
982 }
983 break;
984 default:
985 break;
986 }
987 {
Karl Schimpfd6064a12014-08-27 15:34:58 -0700988 std::string Buffer;
989 raw_string_ostream StrBuf(Buffer);
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700990 StrBuf << "Invalid type vector record: <" << Values[0] << " x " << BaseTy
Karl Schimpfd6064a12014-08-27 15:34:58 -0700991 << ">";
992 Error(StrBuf.str());
Karl Schimpfd6064a12014-08-27 15:34:58 -0700993 }
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700994 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -0700995 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700996 case naclbitc::TYPE_CODE_FUNCTION: {
997 // FUNCTION: [vararg, retty, paramty x N]
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800998 if (!isValidRecordSizeAtLeast(2, "signature"))
Karl Schimpfd6064a12014-08-27 15:34:58 -0700999 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -07001000 if (Values[0])
1001 Error("Function type can't define varargs");
1002 ExtendedType *Ty = Context->getTypeByIDForDefining(NextTypeId++);
1003 Ty->setAsFunctionType();
Jim Stichnoth54f3d512015-12-11 09:53:00 -08001004 auto *FuncTy = cast<FuncSigExtendedType>(Ty);
Karl Schimpf645aa1a2014-10-08 09:05:53 -07001005 FuncTy->setReturnType(Context->getSimpleTypeByID(Values[1]));
Karl Schimpf74cd8832015-06-23 11:05:01 -07001006 for (size_t i = 2, e = Values.size(); i != e; ++i) {
Andrew Scull57e12682015-09-16 11:30:19 -07001007 // Check that type void not used as argument type. Note: PNaCl
1008 // restrictions can't be checked until we know the name, because we have
1009 // to check for intrinsic signatures.
Karl Schimpf645aa1a2014-10-08 09:05:53 -07001010 Ice::Type ArgTy = Context->getSimpleTypeByID(Values[i]);
1011 if (ArgTy == Ice::IceType_void) {
1012 std::string Buffer;
1013 raw_string_ostream StrBuf(Buffer);
1014 StrBuf << "Type for parameter " << (i - 1)
1015 << " not valid. Found: " << ArgTy;
Karl Schimpf645aa1a2014-10-08 09:05:53 -07001016 ArgTy = Ice::IceType_i32;
1017 }
1018 FuncTy->appendArgType(ArgTy);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001019 }
Karl Schimpf645aa1a2014-10-08 09:05:53 -07001020 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001021 }
1022 default:
1023 BlockParserBaseClass::ProcessRecord();
Karl Schimpfd6064a12014-08-27 15:34:58 -07001024 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001025 }
Karl Schimpf645aa1a2014-10-08 09:05:53 -07001026 llvm_unreachable("Unknown type block record not processed!");
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001027}
1028
Karl Schimpf9d98d792014-10-13 15:01:08 -07001029/// Parses the globals block (i.e. global variable declarations and
1030/// corresponding initializers).
Karl Schimpfe8457a22016-03-31 10:20:23 -07001031class GlobalsParser final : public BlockParserBaseClass {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001032 GlobalsParser() = delete;
1033 GlobalsParser(const GlobalsParser &) = delete;
1034 GlobalsParser &operator=(const GlobalsParser &) = delete;
1035
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001036public:
1037 GlobalsParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
Karl Schimpf58455872014-11-03 11:29:39 -08001038 : BlockParserBaseClass(BlockID, EnclosingParser),
1039 Timer(Ice::TimerStack::TT_parseGlobals, getTranslator().getContext()),
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001040 NumFunctionIDs(Context->getNumFunctionIDs()),
John Portoa78e4ba2016-03-15 09:28:04 -07001041 DummyGlobalVar(Ice::VariableDeclaration::create(
1042 Context->getGlobalVariablesPool())),
1043 CurGlobalVar(DummyGlobalVar) {
1044 Context->getGlobalVariablesPool()->willNotBeEmitted(DummyGlobalVar);
1045 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001046
Karl Schimpfe8457a22016-03-31 10:20:23 -07001047 ~GlobalsParser() override = default;
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08001048
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001049 const char *getBlockName() const override { return "globals"; }
1050
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001051private:
Andrew Scull8072bae2015-09-14 16:01:26 -07001052 using GlobalVarsMapType =
1053 std::unordered_map<NaClBcIndexSize_t, Ice::VariableDeclaration *>;
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001054
Karl Schimpf58455872014-11-03 11:29:39 -08001055 Ice::TimerMarker Timer;
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001056
1057 // Holds global variables generated/referenced in the global variables block.
1058 GlobalVarsMapType GlobalVarsMap;
1059
1060 // Holds the number of defined function IDs.
1061 NaClBcIndexSize_t NumFunctionIDs;
1062
Andrew Scull57e12682015-09-16 11:30:19 -07001063 // Holds the specified number of global variables by the count record in the
1064 // global variables block.
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001065 NaClBcIndexSize_t SpecifiedNumberVars = 0;
1066
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001067 // Keeps track of how many initializers are expected for the global variable
Karl Schimpf9d98d792014-10-13 15:01:08 -07001068 // declaration being built.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001069 NaClBcIndexSize_t InitializersNeeded = 0;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001070
Karl Schimpf9d98d792014-10-13 15:01:08 -07001071 // The index of the next global variable declaration.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001072 NaClBcIndexSize_t NextGlobalID = 0;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001073
Andrew Scull57e12682015-09-16 11:30:19 -07001074 // Dummy global variable declaration to guarantee CurGlobalVar is always
1075 // defined (allowing code to not need to check if CurGlobalVar is nullptr).
Karl Schimpf9d98d792014-10-13 15:01:08 -07001076 Ice::VariableDeclaration *DummyGlobalVar;
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001077
Karl Schimpf9d98d792014-10-13 15:01:08 -07001078 // Holds the current global variable declaration being built.
1079 Ice::VariableDeclaration *CurGlobalVar;
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001080
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001081 // Returns the global variable associated with the given Index.
1082 Ice::VariableDeclaration *getGlobalVarByID(NaClBcIndexSize_t Index) {
1083 Ice::VariableDeclaration *&Decl = GlobalVarsMap[Index];
1084 if (Decl == nullptr)
John Portoa78e4ba2016-03-15 09:28:04 -07001085 Decl =
1086 Ice::VariableDeclaration::create(Context->getGlobalVariablesPool());
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001087 return Decl;
1088 }
1089
1090 // Returns the global declaration associated with the given index.
1091 Ice::GlobalDeclaration *getGlobalDeclByID(NaClBcIndexSize_t Index) {
1092 if (Index < NumFunctionIDs)
1093 return Context->getFunctionByID(Index);
1094 return getGlobalVarByID(Index - NumFunctionIDs);
1095 }
1096
1097 // If global variables parsed correctly, install them into the top-level
1098 // context.
1099 void installGlobalVariables() {
1100 // Verify specified number of globals matches number found.
1101 size_t NumGlobals = GlobalVarsMap.size();
1102 if (SpecifiedNumberVars != NumGlobals ||
1103 SpecifiedNumberVars != NextGlobalID) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001104 std::string Buffer;
1105 raw_string_ostream StrBuf(Buffer);
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001106 StrBuf << getBlockName() << " block expects " << SpecifiedNumberVars
1107 << " global variables. Found: " << GlobalVarsMap.size();
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001108 Error(StrBuf.str());
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001109 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001110 }
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001111 // Install global variables into top-level context.
1112 for (size_t I = 0; I < NumGlobals; ++I)
1113 Context->addGlobalDeclaration(GlobalVarsMap[I]);
1114 }
1115
1116 void ExitBlock() override {
1117 verifyNoMissingInitializers();
1118 installGlobalVariables();
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001119 BlockParserBaseClass::ExitBlock();
1120 }
1121
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07001122 void ProcessRecord() override;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001123
Karl Schimpf9d98d792014-10-13 15:01:08 -07001124 // Checks if the number of initializers for the CurGlobalVar is the same as
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001125 // the number found in the bitcode file. If different, and error message is
1126 // generated, and the internal state of the parser is fixed so this condition
1127 // is no longer violated.
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001128 void verifyNoMissingInitializers() {
Karl Schimpf9d98d792014-10-13 15:01:08 -07001129 size_t NumInits = CurGlobalVar->getInitializers().size();
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001130 if (InitializersNeeded != NumInits) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001131 std::string Buffer;
1132 raw_string_ostream StrBuf(Buffer);
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001133 StrBuf << "Global variable @g" << NextGlobalID << " expected "
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001134 << InitializersNeeded << " initializer";
1135 if (InitializersNeeded > 1)
1136 StrBuf << "s";
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001137 StrBuf << ". Found: " << NumInits;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001138 Error(StrBuf.str());
Karl Schimpf9d98d792014-10-13 15:01:08 -07001139 InitializersNeeded = NumInits;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001140 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001141 }
1142};
1143
1144void GlobalsParser::ProcessRecord() {
1145 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1146 switch (Record.GetCode()) {
1147 case naclbitc::GLOBALVAR_COUNT:
1148 // COUNT: [n]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001149 if (!isValidRecordSize(1, "count"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001150 return;
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001151 if (SpecifiedNumberVars || NextGlobalID) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001152 Error("Globals count record not first in block.");
1153 return;
1154 }
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001155 SpecifiedNumberVars = Values[0];
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001156 return;
1157 case naclbitc::GLOBALVAR_VAR: {
1158 // VAR: [align, isconst]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001159 if (!isValidRecordSize(2, "variable"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001160 return;
1161 verifyNoMissingInitializers();
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001162 // Always build the global variable, even if IR generation is turned off.
1163 // This is needed because we need a placeholder in the top-level context
1164 // when no IR is generated.
Karl Schimpf07af2ac2015-09-30 15:33:41 -07001165 uint32_t Alignment =
1166 Context->extractAlignment(this, "Global variable", Values[0]);
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001167 CurGlobalVar = getGlobalVarByID(NextGlobalID);
Jim Stichnoth0d4fc922015-12-13 21:36:33 -08001168 InitializersNeeded = 1;
1169 CurGlobalVar->setAlignment(Alignment);
1170 CurGlobalVar->setIsConstant(Values[1] != 0);
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001171 ++NextGlobalID;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001172 return;
1173 }
1174 case naclbitc::GLOBALVAR_COMPOUND:
1175 // COMPOUND: [size]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001176 if (!isValidRecordSize(1, "compound"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001177 return;
Karl Schimpf9d98d792014-10-13 15:01:08 -07001178 if (!CurGlobalVar->getInitializers().empty()) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001179 Error("Globals compound record not first initializer");
1180 return;
1181 }
1182 if (Values[0] < 2) {
1183 std::string Buffer;
1184 raw_string_ostream StrBuf(Buffer);
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001185 StrBuf << getBlockName()
1186 << " compound record size invalid. Found: " << Values[0];
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001187 Error(StrBuf.str());
1188 return;
1189 }
1190 InitializersNeeded = Values[0];
1191 return;
1192 case naclbitc::GLOBALVAR_ZEROFILL: {
1193 // ZEROFILL: [size]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001194 if (!isValidRecordSize(1, "zerofill"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001195 return;
John Portoa78e4ba2016-03-15 09:28:04 -07001196 auto *Pool = Context->getGlobalVariablesPool();
Karl Schimpf9d98d792014-10-13 15:01:08 -07001197 CurGlobalVar->addInitializer(
John Portoa78e4ba2016-03-15 09:28:04 -07001198 Ice::VariableDeclaration::ZeroInitializer::create(Pool, Values[0]));
Karl Schimpf9d98d792014-10-13 15:01:08 -07001199 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001200 }
1201 case naclbitc::GLOBALVAR_DATA: {
1202 // DATA: [b0, b1, ...]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001203 if (!isValidRecordSizeAtLeast(1, "data"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001204 return;
John Portoa78e4ba2016-03-15 09:28:04 -07001205 auto *Pool = Context->getGlobalVariablesPool();
Karl Schimpf9d98d792014-10-13 15:01:08 -07001206 CurGlobalVar->addInitializer(
John Portoa78e4ba2016-03-15 09:28:04 -07001207 Ice::VariableDeclaration::DataInitializer::create(Pool, Values));
Karl Schimpf9d98d792014-10-13 15:01:08 -07001208 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001209 }
1210 case naclbitc::GLOBALVAR_RELOC: {
1211 // RELOC: [val, [addend]]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001212 if (!isValidRecordSizeInRange(1, 2, "reloc"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001213 return;
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001214 NaClBcIndexSize_t Index = Values[0];
1215 NaClBcIndexSize_t IndexLimit = SpecifiedNumberVars + NumFunctionIDs;
1216 if (Index >= IndexLimit) {
1217 std::string Buffer;
1218 raw_string_ostream StrBuf(Buffer);
1219 StrBuf << "Relocation index " << Index << " to big. Expect index < "
1220 << IndexLimit;
1221 Error(StrBuf.str());
1222 }
Karl Schimpf74cd8832015-06-23 11:05:01 -07001223 uint64_t Offset = 0;
1224 if (Values.size() == 2) {
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001225 Offset = Values[1];
Karl Schimpf74cd8832015-06-23 11:05:01 -07001226 if (Offset > std::numeric_limits<uint32_t>::max()) {
1227 std::string Buffer;
1228 raw_string_ostream StrBuf(Buffer);
1229 StrBuf << "Addend of global reloc record too big: " << Offset;
1230 Error(StrBuf.str());
1231 }
1232 }
John Portoa78e4ba2016-03-15 09:28:04 -07001233 auto *Pool = Context->getGlobalVariablesPool();
John Porto844211e2016-02-04 08:42:48 -08001234 Ice::GlobalContext *Ctx = getTranslator().getContext();
John Porto1bec8bc2015-06-22 10:51:13 -07001235 CurGlobalVar->addInitializer(
1236 Ice::VariableDeclaration::RelocInitializer::create(
John Portoa78e4ba2016-03-15 09:28:04 -07001237 Pool, getGlobalDeclByID(Index),
1238 {Ice::RelocOffset::create(Ctx, Offset)}));
Karl Schimpf9d98d792014-10-13 15:01:08 -07001239 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001240 }
1241 default:
1242 BlockParserBaseClass::ProcessRecord();
1243 return;
1244 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001245}
1246
Karl Schimpfc132b762014-09-11 09:43:47 -07001247/// Base class for parsing a valuesymtab block in the bitcode file.
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001248class ValuesymtabParser : public BlockParserBaseClass {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001249 ValuesymtabParser() = delete;
Jim Stichnoth0795ba02014-10-01 14:23:01 -07001250 ValuesymtabParser(const ValuesymtabParser &) = delete;
1251 void operator=(const ValuesymtabParser &) = delete;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001252
1253public:
Karl Schimpfc132b762014-09-11 09:43:47 -07001254 ValuesymtabParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
1255 : BlockParserBaseClass(BlockID, EnclosingParser) {}
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001256
Jim Stichnothe587d942015-06-22 15:49:04 -07001257 ~ValuesymtabParser() override = default;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001258
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001259 const char *getBlockName() const override { return "valuesymtab"; }
1260
Karl Schimpfc132b762014-09-11 09:43:47 -07001261protected:
Andrew Scull8072bae2015-09-14 16:01:26 -07001262 using StringType = SmallString<128>;
Karl Schimpfc132b762014-09-11 09:43:47 -07001263
Karl Schimpf52863b12015-09-16 13:51:21 -07001264 // Returns the name to identify the kind of symbol table this is
1265 // in error messages.
1266 virtual const char *getTableKind() const = 0;
1267
Karl Schimpfc132b762014-09-11 09:43:47 -07001268 // Associates Name with the value defined by the given Index.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001269 virtual void setValueName(NaClBcIndexSize_t Index, StringType &Name) = 0;
Karl Schimpfc132b762014-09-11 09:43:47 -07001270
1271 // Associates Name with the value defined by the given Index;
Karl Schimpf74cd8832015-06-23 11:05:01 -07001272 virtual void setBbName(NaClBcIndexSize_t Index, StringType &Name) = 0;
Karl Schimpfc132b762014-09-11 09:43:47 -07001273
Karl Schimpf52863b12015-09-16 13:51:21 -07001274 // Reports that the assignment of Name to the value associated with
1275 // index is not possible, for the given Context.
1276 void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index,
1277 StringType &Name);
1278
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001279private:
Karl Schimpf52863b12015-09-16 13:51:21 -07001280 using NamesSetType = std::unordered_set<StringType>;
1281 NamesSetType ValueNames;
1282 NamesSetType BlockNames;
1283
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07001284 void ProcessRecord() override;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001285
Karl Schimpf52863b12015-09-16 13:51:21 -07001286 // Extracts out ConvertedName. Returns true if unique wrt to Names.
1287 bool convertToString(NamesSetType &Names, StringType &ConvertedName) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001288 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1289 for (size_t i = 1, e = Values.size(); i != e; ++i) {
1290 ConvertedName += static_cast<char>(Values[i]);
1291 }
Karl Schimpf52863b12015-09-16 13:51:21 -07001292 auto Pair = Names.insert(ConvertedName);
1293 return Pair.second;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001294 }
Karl Schimpf52863b12015-09-16 13:51:21 -07001295
1296 void ReportDuplicateName(const char *NameCat, StringType &Name);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001297};
1298
Karl Schimpf52863b12015-09-16 13:51:21 -07001299void ValuesymtabParser::reportUnableToAssign(const char *Context,
1300 NaClBcIndexSize_t Index,
1301 StringType &Name) {
1302 std::string Buffer;
1303 raw_string_ostream StrBuf(Buffer);
1304 StrBuf << getTableKind() << " " << getBlockName() << ": " << Context
1305 << " name '" << Name << "' can't be associated with index " << Index;
1306 Error(StrBuf.str());
1307}
1308
1309void ValuesymtabParser::ReportDuplicateName(const char *NameCat,
1310 StringType &Name) {
1311 std::string Buffer;
1312 raw_string_ostream StrBuf(Buffer);
1313 StrBuf << getTableKind() << " " << getBlockName() << " defines duplicate "
1314 << NameCat << " name: '" << Name << "'";
1315 Error(StrBuf.str());
1316}
1317
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001318void ValuesymtabParser::ProcessRecord() {
1319 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1320 StringType ConvertedName;
1321 switch (Record.GetCode()) {
1322 case naclbitc::VST_CODE_ENTRY: {
1323 // VST_ENTRY: [ValueId, namechar x N]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001324 if (!isValidRecordSizeAtLeast(2, "value entry"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001325 return;
Karl Schimpf52863b12015-09-16 13:51:21 -07001326 if (convertToString(ValueNames, ConvertedName))
1327 setValueName(Values[0], ConvertedName);
1328 else
1329 ReportDuplicateName("value", ConvertedName);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001330 return;
1331 }
1332 case naclbitc::VST_CODE_BBENTRY: {
1333 // VST_BBENTRY: [BbId, namechar x N]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001334 if (!isValidRecordSizeAtLeast(2, "basic block entry"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001335 return;
Karl Schimpf52863b12015-09-16 13:51:21 -07001336 if (convertToString(BlockNames, ConvertedName))
1337 setBbName(Values[0], ConvertedName);
1338 else
1339 ReportDuplicateName("block", ConvertedName);
Karl Schimpfc132b762014-09-11 09:43:47 -07001340 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001341 }
1342 default:
1343 break;
1344 }
1345 // If reached, don't know how to handle record.
1346 BlockParserBaseClass::ProcessRecord();
1347 return;
1348}
1349
Karl Schimpfd6064a12014-08-27 15:34:58 -07001350/// Parses function blocks in the bitcode file.
Karl Schimpfe8457a22016-03-31 10:20:23 -07001351class FunctionParser final : public BlockParserBaseClass {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001352 FunctionParser() = delete;
Jim Stichnoth0795ba02014-10-01 14:23:01 -07001353 FunctionParser(const FunctionParser &) = delete;
1354 FunctionParser &operator=(const FunctionParser &) = delete;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001355
1356public:
Karl Schimpfe8457a22016-03-31 10:20:23 -07001357 FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser,
1358 NaClBcIndexSize_t FcnId)
Karl Schimpfd6064a12014-08-27 15:34:58 -07001359 : BlockParserBaseClass(BlockID, EnclosingParser),
Karl Schimpf58455872014-11-03 11:29:39 -08001360 Timer(Ice::TimerStack::TT_parseFunctions, getTranslator().getContext()),
Karl Schimpfe8457a22016-03-31 10:20:23 -07001361 Func(nullptr), FuncDecl(Context->getFunctionByID(FcnId)),
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001362 CachedNumGlobalValueIDs(Context->getNumGlobalIDs()),
Jim Stichnotheafb56c2015-06-22 10:35:22 -07001363 NextLocalInstIndex(Context->getNumGlobalIDs()) {}
Jim Stichnoth8e928382015-02-02 17:03:08 -08001364
Karl Schimpfe8457a22016-03-31 10:20:23 -07001365 FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser,
1366 NaClBcIndexSize_t FcnId, NaClBitstreamCursor &Cursor)
1367 : BlockParserBaseClass(BlockID, EnclosingParser, Cursor),
1368 Timer(Ice::TimerStack::TT_parseFunctions, getTranslator().getContext()),
1369 Func(nullptr), FuncDecl(Context->getFunctionByID(FcnId)),
1370 CachedNumGlobalValueIDs(Context->getNumGlobalIDs()),
1371 NextLocalInstIndex(Context->getNumGlobalIDs()) {}
1372
1373 std::unique_ptr<Ice::Cfg> parseFunction(uint32_t SeqNumber) {
John Portoe82b5602016-02-24 15:58:55 -08001374 bool ParserResult;
Karl Schimpfe8457a22016-03-31 10:20:23 -07001375 Ice::GlobalContext *Ctx = getTranslator().getContext();
John Portoe82b5602016-02-24 15:58:55 -08001376 {
Karl Schimpfe8457a22016-03-31 10:20:23 -07001377 Ice::TimerMarker T(Ctx, FuncDecl->getName().toStringOrEmpty());
Jim Stichnothb88d8c82016-03-11 15:33:00 -08001378 // Note: The Cfg is created, even when IR generation is disabled. This is
1379 // done to install a CfgLocalAllocator for various internal containers.
Jim Stichnoth467ffe52016-03-29 15:01:06 -07001380 Ice::GlobalContext *Ctx = getTranslator().getContext();
Karl Schimpfe8457a22016-03-31 10:20:23 -07001381 Func = Ice::Cfg::create(Ctx, SeqNumber);
Jim Stichnothb88d8c82016-03-11 15:33:00 -08001382
John Portoe82b5602016-02-24 15:58:55 -08001383 Ice::CfgLocalAllocatorScope _(Func.get());
Jim Stichnoth8e928382015-02-02 17:03:08 -08001384
John Portoe82b5602016-02-24 15:58:55 -08001385 // TODO(kschimpf) Clean up API to add a function signature to a CFG.
1386 const Ice::FuncSigType &Signature = FuncDecl->getSignature();
Jim Stichnoth0d4fc922015-12-13 21:36:33 -08001387
John Portoe82b5602016-02-24 15:58:55 -08001388 Func->setFunctionName(FuncDecl->getName());
1389 Func->setReturnType(Signature.getReturnType());
1390 Func->setInternal(FuncDecl->getLinkage() == GlobalValue::InternalLinkage);
1391 CurrentNode = installNextBasicBlock();
1392 Func->setEntryNode(CurrentNode);
1393 for (Ice::Type ArgType : Signature.getArgList()) {
1394 Func->addArg(getNextInstVar(ArgType));
1395 }
1396
1397 ParserResult = ParseThisBlock();
Jim Stichnoth8e928382015-02-02 17:03:08 -08001398 }
1399
Karl Schimpfe8457a22016-03-31 10:20:23 -07001400 if (ParserResult || BlockHasError)
1401 Func->setError("Unable to parse function");
1402
1403 return std::move(Func);
Karl Schimpfd6064a12014-08-27 15:34:58 -07001404 }
1405
Karl Schimpfe8457a22016-03-31 10:20:23 -07001406 ~FunctionParser() override = default;
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08001407
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001408 const char *getBlockName() const override { return "function"; }
1409
Jim Stichnoth8e928382015-02-02 17:03:08 -08001410 Ice::Cfg *getFunc() const { return Func.get(); }
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001411
Karl Schimpf74cd8832015-06-23 11:05:01 -07001412 size_t getNumGlobalIDs() const { return CachedNumGlobalValueIDs; }
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001413
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08001414 void setNextLocalInstIndex(Ice::Operand *Op) {
1415 setOperand(NextLocalInstIndex++, Op);
1416 }
Karl Schimpfd6064a12014-08-27 15:34:58 -07001417
Karl Schimpff12355e2014-09-08 13:41:09 -07001418 // Set the next constant ID to the given constant C.
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08001419 void setNextConstantID(Ice::Constant *C) { setNextLocalInstIndex(C); }
Karl Schimpff12355e2014-09-08 13:41:09 -07001420
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001421 // Returns the value referenced by the given value Index.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001422 Ice::Operand *getOperand(NaClBcIndexSize_t Index) {
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001423 if (Index < CachedNumGlobalValueIDs) {
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -08001424 return Context->getGlobalConstantByID(Index);
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001425 }
Karl Schimpf74cd8832015-06-23 11:05:01 -07001426 NaClBcIndexSize_t LocalIndex = Index - CachedNumGlobalValueIDs;
Karl Schimpf9d25e622015-09-16 13:47:01 -07001427 if (LocalIndex >= LocalOperands.size())
1428 reportGetOperandUndefined(Index);
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001429 Ice::Operand *Op = LocalOperands[LocalIndex];
Karl Schimpf9d25e622015-09-16 13:47:01 -07001430 if (Op == nullptr)
1431 reportGetOperandUndefined(Index);
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001432 return Op;
1433 }
1434
Karl Schimpfd6064a12014-08-27 15:34:58 -07001435private:
Karl Schimpf58455872014-11-03 11:29:39 -08001436 Ice::TimerMarker Timer;
Karl Schimpf98ed4462015-08-14 13:08:42 -07001437 // The number of words in the bitstream defining the function block.
1438 uint64_t NumBytesDefiningFunction = 0;
Karl Schimpf7a993272015-08-17 12:43:29 -07001439 // Maximum number of records that can appear in the function block, based on
1440 // the number of bytes defining the function block.
1441 uint64_t MaxRecordsInBlock = 0;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001442 // The corresponding ICE function defined by the function block.
Jim Stichnoth8e928382015-02-02 17:03:08 -08001443 std::unique_ptr<Ice::Cfg> Func;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001444 // The index to the current basic block being built.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001445 NaClBcIndexSize_t CurrentBbIndex = 0;
Karl Schimpf98ed4462015-08-14 13:08:42 -07001446 // The number of basic blocks declared for the function block.
1447 NaClBcIndexSize_t DeclaredNumberBbs = 0;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001448 // The basic block being built.
Jim Stichnotheafb56c2015-06-22 10:35:22 -07001449 Ice::CfgNode *CurrentNode = nullptr;
Karl Schimpf9d98d792014-10-13 15:01:08 -07001450 // The corresponding function declaration.
1451 Ice::FunctionDeclaration *FuncDecl;
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001452 // Holds the dividing point between local and global absolute value indices.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001453 size_t CachedNumGlobalValueIDs;
Andrew Scull57e12682015-09-16 11:30:19 -07001454 // Holds operands local to the function block, based on indices defined in
1455 // the bitcode file.
Karl Schimpf209318a2015-08-20 13:24:02 -07001456 Ice::OperandList LocalOperands;
Andrew Scull57e12682015-09-16 11:30:19 -07001457 // Holds the index within LocalOperands corresponding to the next instruction
1458 // that generates a value.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001459 NaClBcIndexSize_t NextLocalInstIndex;
Andrew Scull57e12682015-09-16 11:30:19 -07001460 // True if the last processed instruction was a terminating instruction.
Jim Stichnotheafb56c2015-06-22 10:35:22 -07001461 bool InstIsTerminating = false;
Karl Schimpf41689df2014-09-10 14:36:07 -07001462
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07001463 bool ParseBlock(unsigned BlockID) override;
Karl Schimpff12355e2014-09-08 13:41:09 -07001464
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07001465 void ProcessRecord() override;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001466
Karl Schimpfe8457a22016-03-31 10:20:23 -07001467 void EnterBlock(unsigned NumWords) override {
Karl Schimpf98ed4462015-08-14 13:08:42 -07001468 // Note: Bitstream defines words as 32-bit values.
1469 NumBytesDefiningFunction = NumWords * sizeof(uint32_t);
Karl Schimpf7a993272015-08-17 12:43:29 -07001470 // We know that all records are minimally defined by a two-bit abreviation.
1471 MaxRecordsInBlock = NumBytesDefiningFunction * (CHAR_BIT >> 1);
Karl Schimpf98ed4462015-08-14 13:08:42 -07001472 }
1473
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07001474 void ExitBlock() override;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001475
Karl Schimpf98ed4462015-08-14 13:08:42 -07001476 // Creates and appends a new basic block to the list of basic blocks.
1477 Ice::CfgNode *installNextBasicBlock() {
Karl Schimpf98ed4462015-08-14 13:08:42 -07001478 Ice::CfgNode *Node = Func->makeNode();
1479 return Node;
1480 }
1481
1482 // Returns the Index-th basic block in the list of basic blocks.
1483 Ice::CfgNode *getBasicBlock(NaClBcIndexSize_t Index) {
Karl Schimpf98ed4462015-08-14 13:08:42 -07001484 if (Index >= Func->getNumNodes()) {
1485 std::string Buffer;
1486 raw_string_ostream StrBuf(Buffer);
1487 StrBuf << "Reference to basic block " << Index
1488 << " not found. Must be less than " << Func->getNumNodes();
1489 Error(StrBuf.str());
1490 Index = 0;
1491 }
1492 return Func->getNodes()[Index];
1493 }
1494
Andrew Scull57e12682015-09-16 11:30:19 -07001495 // Returns the Index-th basic block in the list of basic blocks. Assumes
1496 // Index corresponds to a branch instruction. Hence, if the branch references
1497 // the entry block, it also generates a corresponding error.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001498 Ice::CfgNode *getBranchBasicBlock(NaClBcIndexSize_t Index) {
Karl Schimpfc836acb2014-09-05 08:32:47 -07001499 if (Index == 0) {
1500 Error("Branch to entry block not allowed");
Karl Schimpfc836acb2014-09-05 08:32:47 -07001501 }
Karl Schimpf47661562014-09-11 14:42:49 -07001502 return getBasicBlock(Index);
Karl Schimpfc836acb2014-09-05 08:32:47 -07001503 }
1504
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001505 // Generate an instruction variable with type Ty.
1506 Ice::Variable *createInstVar(Ice::Type Ty) {
Karl Schimpf47661562014-09-11 14:42:49 -07001507 if (Ty == Ice::IceType_void) {
1508 Error("Can't define instruction value using type void");
1509 // Recover since we can't throw an exception.
1510 Ty = Ice::IceType_i32;
1511 }
Jim Stichnoth144cdce2014-09-22 16:02:59 -07001512 return Func->makeVariable(Ty);
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001513 }
1514
1515 // Generates the next available local variable using the given type.
1516 Ice::Variable *getNextInstVar(Ice::Type Ty) {
1517 assert(NextLocalInstIndex >= CachedNumGlobalValueIDs);
1518 // Before creating one, see if a forwardtyperef has already defined it.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001519 NaClBcIndexSize_t LocalIndex = NextLocalInstIndex - CachedNumGlobalValueIDs;
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001520 if (LocalIndex < LocalOperands.size()) {
1521 Ice::Operand *Op = LocalOperands[LocalIndex];
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001522 if (Op != nullptr) {
Jim Stichnoth54f3d512015-12-11 09:53:00 -08001523 if (auto *Var = dyn_cast<Ice::Variable>(Op)) {
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001524 if (Var->getType() == Ty) {
1525 ++NextLocalInstIndex;
1526 return Var;
1527 }
1528 }
1529 std::string Buffer;
1530 raw_string_ostream StrBuf(Buffer);
1531 StrBuf << "Illegal forward referenced instruction ("
1532 << NextLocalInstIndex << "): " << *Op;
1533 Error(StrBuf.str());
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001534 ++NextLocalInstIndex;
1535 return createInstVar(Ty);
1536 }
1537 }
1538 Ice::Variable *Var = createInstVar(Ty);
1539 setOperand(NextLocalInstIndex++, Var);
Karl Schimpfd6064a12014-08-27 15:34:58 -07001540 return Var;
1541 }
1542
Andrew Scull57e12682015-09-16 11:30:19 -07001543 // Converts a relative index (wrt to BaseIndex) to an absolute value index.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001544 NaClBcIndexSize_t convertRelativeToAbsIndex(NaClRelBcIndexSize_t Id,
1545 NaClRelBcIndexSize_t BaseIndex) {
Karl Schimpf47661562014-09-11 14:42:49 -07001546 if (BaseIndex < Id) {
Karl Schimpfd6064a12014-08-27 15:34:58 -07001547 std::string Buffer;
1548 raw_string_ostream StrBuf(Buffer);
1549 StrBuf << "Invalid relative value id: " << Id
Karl Schimpf47661562014-09-11 14:42:49 -07001550 << " (must be <= " << BaseIndex << ")";
Karl Schimpfd6064a12014-08-27 15:34:58 -07001551 Error(StrBuf.str());
Karl Schimpfd6064a12014-08-27 15:34:58 -07001552 return 0;
1553 }
Karl Schimpf47661562014-09-11 14:42:49 -07001554 return BaseIndex - Id;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001555 }
1556
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001557 // Sets element Index (in the local operands list) to Op.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001558 void setOperand(NaClBcIndexSize_t Index, Ice::Operand *Op) {
Jim Stichnoth0d4fc922015-12-13 21:36:33 -08001559 assert(Op);
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001560 // Check if simple push works.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001561 NaClBcIndexSize_t LocalIndex = Index - CachedNumGlobalValueIDs;
Karl Schimpf7a993272015-08-17 12:43:29 -07001562 if (LocalIndex == LocalOperands.size()) {
1563 LocalOperands.push_back(Op);
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001564 return;
1565 }
1566
Karl Schimpf7a993272015-08-17 12:43:29 -07001567 // Must be forward reference, expand vector to accommodate.
1568 if (LocalIndex >= LocalOperands.size()) {
1569 if (LocalIndex > MaxRecordsInBlock) {
1570 std::string Buffer;
1571 raw_string_ostream StrBuf(Buffer);
1572 StrBuf << "Forward reference @" << Index << " too big. Have "
1573 << CachedNumGlobalValueIDs << " globals and function contains "
1574 << NumBytesDefiningFunction << " bytes";
1575 Fatal(StrBuf.str());
1576 // Recover by using index one beyond the maximal allowed.
1577 LocalIndex = MaxRecordsInBlock;
1578 }
Jim Stichnoth2f00bf62016-03-11 14:59:43 -08001579 Ice::Utils::reserveAndResize(LocalOperands, LocalIndex + 1);
Karl Schimpf7a993272015-08-17 12:43:29 -07001580 }
1581
1582 // If element not defined, set it.
1583 Ice::Operand *OldOp = LocalOperands[LocalIndex];
1584 if (OldOp == nullptr) {
1585 LocalOperands[LocalIndex] = Op;
1586 return;
1587 }
1588
1589 // See if forward reference matches.
1590 if (OldOp == Op)
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001591 return;
1592
1593 // Error has occurred.
1594 std::string Buffer;
1595 raw_string_ostream StrBuf(Buffer);
Karl Schimpfd1a971a2014-09-17 15:38:17 -07001596 StrBuf << "Multiple definitions for index " << Index << ": " << *Op
Karl Schimpf7a993272015-08-17 12:43:29 -07001597 << " and " << *OldOp;
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001598 Error(StrBuf.str());
Karl Schimpf7a993272015-08-17 12:43:29 -07001599 LocalOperands[LocalIndex] = Op;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001600 }
1601
Andrew Scull57e12682015-09-16 11:30:19 -07001602 // Returns the relative operand (wrt to BaseIndex) referenced by the given
1603 // value Index.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001604 Ice::Operand *getRelativeOperand(NaClBcIndexSize_t Index,
1605 NaClBcIndexSize_t BaseIndex) {
Karl Schimpf47661562014-09-11 14:42:49 -07001606 return getOperand(convertRelativeToAbsIndex(Index, BaseIndex));
1607 }
1608
1609 // Returns the absolute index of the next value generating instruction.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001610 NaClBcIndexSize_t getNextInstIndex() const { return NextLocalInstIndex; }
Karl Schimpf71ba8222014-09-03 09:46:24 -07001611
Andrew Scull57e12682015-09-16 11:30:19 -07001612 // Generates type error message for binary operator Op operating on Type
1613 // OpTy.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001614 void reportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy);
Karl Schimpfd6064a12014-08-27 15:34:58 -07001615
Andrew Scull57e12682015-09-16 11:30:19 -07001616 // Validates if integer logical Op, for type OpTy, is valid. Returns true if
1617 // valid. Otherwise generates error message and returns false.
Karl Schimpfd6064a12014-08-27 15:34:58 -07001618 bool isValidIntegerLogicalOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
1619 if (Ice::isIntegerType(OpTy))
1620 return true;
Karl Schimpf74cd8832015-06-23 11:05:01 -07001621 reportInvalidBinaryOp(Op, OpTy);
Karl Schimpfd6064a12014-08-27 15:34:58 -07001622 return false;
1623 }
1624
Andrew Scull57e12682015-09-16 11:30:19 -07001625 // Validates if integer (or vector of integers) arithmetic Op, for type OpTy,
1626 // is valid. Returns true if valid. Otherwise generates error message and
1627 // returns false.
Karl Schimpfd6064a12014-08-27 15:34:58 -07001628 bool isValidIntegerArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
1629 if (Ice::isIntegerArithmeticType(OpTy))
1630 return true;
Karl Schimpf74cd8832015-06-23 11:05:01 -07001631 reportInvalidBinaryOp(Op, OpTy);
Karl Schimpfd6064a12014-08-27 15:34:58 -07001632 return false;
1633 }
1634
Andrew Scull57e12682015-09-16 11:30:19 -07001635 // Checks if floating arithmetic Op, for type OpTy, is valid. Returns true if
1636 // valid. Otherwise generates an error message and returns false;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001637 bool isValidFloatingArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
1638 if (Ice::isFloatingType(OpTy))
1639 return true;
Karl Schimpf74cd8832015-06-23 11:05:01 -07001640 reportInvalidBinaryOp(Op, OpTy);
Karl Schimpfd6064a12014-08-27 15:34:58 -07001641 return false;
1642 }
1643
Andrew Scull57e12682015-09-16 11:30:19 -07001644 // Checks if the type of operand Op is the valid pointer type, for the given
1645 // InstructionName. Returns true if valid. Otherwise generates an error
1646 // message and returns false.
Karl Schimpf41689df2014-09-10 14:36:07 -07001647 bool isValidPointerType(Ice::Operand *Op, const char *InstructionName) {
Karl Schimpf4019f082014-12-15 13:45:00 -08001648 Ice::Type PtrType = Ice::getPointerType();
Karl Schimpf41689df2014-09-10 14:36:07 -07001649 if (Op->getType() == PtrType)
1650 return true;
1651 std::string Buffer;
1652 raw_string_ostream StrBuf(Buffer);
1653 StrBuf << InstructionName << " address not " << PtrType
Karl Schimpffc0a52d2015-09-28 11:22:55 -07001654 << ". Found: " << Op->getType();
Karl Schimpf41689df2014-09-10 14:36:07 -07001655 Error(StrBuf.str());
1656 return false;
1657 }
1658
Andrew Scull57e12682015-09-16 11:30:19 -07001659 // Checks if loading/storing a value of type Ty is allowed. Returns true if
1660 // Valid. Otherwise generates an error message and returns false.
Karl Schimpf41689df2014-09-10 14:36:07 -07001661 bool isValidLoadStoreType(Ice::Type Ty, const char *InstructionName) {
1662 if (isLoadStoreType(Ty))
1663 return true;
1664 std::string Buffer;
1665 raw_string_ostream StrBuf(Buffer);
1666 StrBuf << InstructionName << " type not allowed: " << Ty << "*";
1667 Error(StrBuf.str());
1668 return false;
1669 }
1670
Andrew Scull57e12682015-09-16 11:30:19 -07001671 // Checks if loading/storing a value of type Ty is allowed for the given
1672 // Alignment. Otherwise generates an error message and returns false.
Karl Schimpff875d452014-12-09 13:50:07 -08001673 bool isValidLoadStoreAlignment(size_t Alignment, Ice::Type Ty,
Karl Schimpf41689df2014-09-10 14:36:07 -07001674 const char *InstructionName) {
1675 if (!isValidLoadStoreType(Ty, InstructionName))
1676 return false;
Karl Schimpff875d452014-12-09 13:50:07 -08001677 if (isAllowedAlignment(Alignment, Ty))
Karl Schimpf41689df2014-09-10 14:36:07 -07001678 return true;
1679 std::string Buffer;
1680 raw_string_ostream StrBuf(Buffer);
1681 StrBuf << InstructionName << " " << Ty << "*: not allowed for alignment "
1682 << Alignment;
1683 Error(StrBuf.str());
1684 return false;
1685 }
1686
Karl Schimpff875d452014-12-09 13:50:07 -08001687 // Defines if the given alignment is valid for the given type. Simplified
Andrew Scull57e12682015-09-16 11:30:19 -07001688 // version of PNaClABIProps::isAllowedAlignment, based on API's offered for
1689 // Ice::Type.
Karl Schimpff875d452014-12-09 13:50:07 -08001690 bool isAllowedAlignment(size_t Alignment, Ice::Type Ty) const {
1691 return Alignment == typeAlignInBytes(Ty) ||
1692 (Alignment == 1 && !isVectorType(Ty));
1693 }
1694
Karl Schimpfaff9fa22014-10-29 14:32:07 -07001695 // Types of errors that can occur for insertelement and extractelement
1696 // instructions.
1697 enum VectorIndexCheckValue {
1698 VectorIndexNotVector,
1699 VectorIndexNotConstant,
1700 VectorIndexNotInRange,
1701 VectorIndexNotI32,
1702 VectorIndexValid
1703 };
1704
1705 void dumpVectorIndexCheckValue(raw_ostream &Stream,
1706 VectorIndexCheckValue Value) const {
Jim Stichnoth20b71f52015-06-24 15:52:24 -07001707 if (!Ice::BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -08001708 return;
Karl Schimpfaff9fa22014-10-29 14:32:07 -07001709 switch (Value) {
Karl Schimpfaff9fa22014-10-29 14:32:07 -07001710 case VectorIndexNotVector:
1711 Stream << "Vector index on non vector";
1712 break;
1713 case VectorIndexNotConstant:
1714 Stream << "Vector index not integer constant";
1715 break;
1716 case VectorIndexNotInRange:
1717 Stream << "Vector index not in range of vector";
1718 break;
1719 case VectorIndexNotI32:
1720 Stream << "Vector index not of type " << Ice::IceType_i32;
1721 break;
1722 case VectorIndexValid:
1723 Stream << "Valid vector index";
1724 break;
1725 }
1726 }
1727
1728 // Returns whether the given vector index (for insertelement and
1729 // extractelement instructions) is valid.
1730 VectorIndexCheckValue validateVectorIndex(const Ice::Operand *Vec,
1731 const Ice::Operand *Index) const {
1732 Ice::Type VecType = Vec->getType();
1733 if (!Ice::isVectorType(VecType))
1734 return VectorIndexNotVector;
1735 const auto *C = dyn_cast<Ice::ConstantInteger32>(Index);
1736 if (C == nullptr)
1737 return VectorIndexNotConstant;
Jim Stichnothd2cb4362014-11-20 11:24:42 -08001738 if (static_cast<size_t>(C->getValue()) >= typeNumElements(VecType))
Karl Schimpfaff9fa22014-10-29 14:32:07 -07001739 return VectorIndexNotInRange;
1740 if (Index->getType() != Ice::IceType_i32)
1741 return VectorIndexNotI32;
1742 return VectorIndexValid;
1743 }
1744
Andrew Scull57e12682015-09-16 11:30:19 -07001745 // Takes the PNaCl bitcode binary operator Opcode, and the opcode type Ty,
1746 // and sets Op to the corresponding ICE binary opcode. Returns true if able
1747 // to convert, false otherwise.
Karl Schimpfd6064a12014-08-27 15:34:58 -07001748 bool convertBinopOpcode(unsigned Opcode, Ice::Type Ty,
1749 Ice::InstArithmetic::OpKind &Op) {
Karl Schimpf9bb188d2014-12-10 12:54:34 -08001750 switch (Opcode) {
Karl Schimpfd6064a12014-08-27 15:34:58 -07001751 default: {
Karl Schimpf9bb188d2014-12-10 12:54:34 -08001752 std::string Buffer;
1753 raw_string_ostream StrBuf(Buffer);
1754 StrBuf << "Binary opcode " << Opcode << "not understood for type " << Ty;
1755 Error(StrBuf.str());
Karl Schimpfd6064a12014-08-27 15:34:58 -07001756 Op = Ice::InstArithmetic::Add;
1757 return false;
1758 }
Karl Schimpf9bb188d2014-12-10 12:54:34 -08001759 case naclbitc::BINOP_ADD:
1760 if (Ice::isIntegerType(Ty)) {
1761 Op = Ice::InstArithmetic::Add;
1762 return isValidIntegerArithOp(Op, Ty);
1763 } else {
1764 Op = Ice::InstArithmetic::Fadd;
1765 return isValidFloatingArithOp(Op, Ty);
1766 }
1767 case naclbitc::BINOP_SUB:
1768 if (Ice::isIntegerType(Ty)) {
1769 Op = Ice::InstArithmetic::Sub;
1770 return isValidIntegerArithOp(Op, Ty);
1771 } else {
1772 Op = Ice::InstArithmetic::Fsub;
1773 return isValidFloatingArithOp(Op, Ty);
1774 }
1775 case naclbitc::BINOP_MUL:
1776 if (Ice::isIntegerType(Ty)) {
1777 Op = Ice::InstArithmetic::Mul;
1778 return isValidIntegerArithOp(Op, Ty);
1779 } else {
1780 Op = Ice::InstArithmetic::Fmul;
1781 return isValidFloatingArithOp(Op, Ty);
1782 }
1783 case naclbitc::BINOP_UDIV:
Karl Schimpfd6064a12014-08-27 15:34:58 -07001784 Op = Ice::InstArithmetic::Udiv;
1785 return isValidIntegerArithOp(Op, Ty);
Karl Schimpf9bb188d2014-12-10 12:54:34 -08001786 case naclbitc::BINOP_SDIV:
1787 if (Ice::isIntegerType(Ty)) {
1788 Op = Ice::InstArithmetic::Sdiv;
1789 return isValidIntegerArithOp(Op, Ty);
1790 } else {
1791 Op = Ice::InstArithmetic::Fdiv;
1792 return isValidFloatingArithOp(Op, Ty);
1793 }
1794 case naclbitc::BINOP_UREM:
Karl Schimpfd6064a12014-08-27 15:34:58 -07001795 Op = Ice::InstArithmetic::Urem;
1796 return isValidIntegerArithOp(Op, Ty);
Karl Schimpf9bb188d2014-12-10 12:54:34 -08001797 case naclbitc::BINOP_SREM:
1798 if (Ice::isIntegerType(Ty)) {
1799 Op = Ice::InstArithmetic::Srem;
1800 return isValidIntegerArithOp(Op, Ty);
1801 } else {
1802 Op = Ice::InstArithmetic::Frem;
1803 return isValidFloatingArithOp(Op, Ty);
1804 }
1805 case naclbitc::BINOP_SHL:
Karl Schimpfd6064a12014-08-27 15:34:58 -07001806 Op = Ice::InstArithmetic::Shl;
1807 return isValidIntegerArithOp(Op, Ty);
Karl Schimpf9bb188d2014-12-10 12:54:34 -08001808 case naclbitc::BINOP_LSHR:
Karl Schimpfd6064a12014-08-27 15:34:58 -07001809 Op = Ice::InstArithmetic::Lshr;
1810 return isValidIntegerArithOp(Op, Ty);
Karl Schimpf9bb188d2014-12-10 12:54:34 -08001811 case naclbitc::BINOP_ASHR:
Karl Schimpfd6064a12014-08-27 15:34:58 -07001812 Op = Ice::InstArithmetic::Ashr;
1813 return isValidIntegerArithOp(Op, Ty);
Karl Schimpf9bb188d2014-12-10 12:54:34 -08001814 case naclbitc::BINOP_AND:
Karl Schimpfd6064a12014-08-27 15:34:58 -07001815 Op = Ice::InstArithmetic::And;
1816 return isValidIntegerLogicalOp(Op, Ty);
Karl Schimpf9bb188d2014-12-10 12:54:34 -08001817 case naclbitc::BINOP_OR:
Karl Schimpfd6064a12014-08-27 15:34:58 -07001818 Op = Ice::InstArithmetic::Or;
1819 return isValidIntegerLogicalOp(Op, Ty);
Karl Schimpf9bb188d2014-12-10 12:54:34 -08001820 case naclbitc::BINOP_XOR:
Karl Schimpfd6064a12014-08-27 15:34:58 -07001821 Op = Ice::InstArithmetic::Xor;
1822 return isValidIntegerLogicalOp(Op, Ty);
1823 }
1824 }
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001825
Andrew Scull57e12682015-09-16 11:30:19 -07001826 /// Simplifies out vector types from Type1 and Type2, if both are vectors of
1827 /// the same size. Returns true iff both are vectors of the same size, or are
1828 /// both scalar types.
Karl Schimpfbf170372014-12-15 10:16:31 -08001829 static bool simplifyOutCommonVectorType(Ice::Type &Type1, Ice::Type &Type2) {
1830 bool IsType1Vector = isVectorType(Type1);
1831 bool IsType2Vector = isVectorType(Type2);
1832 if (IsType1Vector != IsType2Vector)
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001833 return false;
Karl Schimpfbf170372014-12-15 10:16:31 -08001834 if (!IsType1Vector)
1835 return true;
1836 if (typeNumElements(Type1) != typeNumElements(Type2))
1837 return false;
1838 Type1 = typeElementType(Type1);
1839 Type2 = typeElementType(Type2);
1840 return true;
1841 }
1842
1843 /// Returns true iff an integer truncation from SourceType to TargetType is
1844 /// valid.
1845 static bool isIntTruncCastValid(Ice::Type SourceType, Ice::Type TargetType) {
Jim Stichnothdd842db2015-01-27 12:53:53 -08001846 return Ice::isIntegerType(SourceType) && Ice::isIntegerType(TargetType) &&
1847 simplifyOutCommonVectorType(SourceType, TargetType) &&
1848 getScalarIntBitWidth(SourceType) > getScalarIntBitWidth(TargetType);
Karl Schimpfbf170372014-12-15 10:16:31 -08001849 }
1850
1851 /// Returns true iff a floating type truncation from SourceType to TargetType
1852 /// is valid.
1853 static bool isFloatTruncCastValid(Ice::Type SourceType,
1854 Ice::Type TargetType) {
Jim Stichnothdd842db2015-01-27 12:53:53 -08001855 return simplifyOutCommonVectorType(SourceType, TargetType) &&
1856 SourceType == Ice::IceType_f64 && TargetType == Ice::IceType_f32;
Karl Schimpfbf170372014-12-15 10:16:31 -08001857 }
1858
1859 /// Returns true iff an integer extension from SourceType to TargetType is
1860 /// valid.
1861 static bool isIntExtCastValid(Ice::Type SourceType, Ice::Type TargetType) {
1862 return isIntTruncCastValid(TargetType, SourceType);
1863 }
1864
1865 /// Returns true iff a floating type extension from SourceType to TargetType
1866 /// is valid.
1867 static bool isFloatExtCastValid(Ice::Type SourceType, Ice::Type TargetType) {
1868 return isFloatTruncCastValid(TargetType, SourceType);
1869 }
1870
Andrew Scull57e12682015-09-16 11:30:19 -07001871 /// Returns true iff a cast from floating type SourceType to integer type
1872 /// TargetType is valid.
Karl Schimpfbf170372014-12-15 10:16:31 -08001873 static bool isFloatToIntCastValid(Ice::Type SourceType,
1874 Ice::Type TargetType) {
1875 if (!(Ice::isFloatingType(SourceType) && Ice::isIntegerType(TargetType)))
1876 return false;
1877 bool IsSourceVector = isVectorType(SourceType);
1878 bool IsTargetVector = isVectorType(TargetType);
1879 if (IsSourceVector != IsTargetVector)
1880 return false;
1881 if (IsSourceVector) {
1882 return typeNumElements(SourceType) == typeNumElements(TargetType);
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001883 }
1884 return true;
1885 }
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07001886
Andrew Scull57e12682015-09-16 11:30:19 -07001887 /// Returns true iff a cast from integer type SourceType to floating type
1888 /// TargetType is valid.
Karl Schimpfbf170372014-12-15 10:16:31 -08001889 static bool isIntToFloatCastValid(Ice::Type SourceType,
1890 Ice::Type TargetType) {
1891 return isFloatToIntCastValid(TargetType, SourceType);
1892 }
1893
Andrew Scull57e12682015-09-16 11:30:19 -07001894 /// Returns the number of bits used to model type Ty when defining the bitcast
1895 /// instruction.
Karl Schimpfbf170372014-12-15 10:16:31 -08001896 static Ice::SizeT bitcastSizeInBits(Ice::Type Ty) {
1897 if (Ice::isVectorType(Ty))
1898 return Ice::typeNumElements(Ty) *
1899 bitcastSizeInBits(Ice::typeElementType(Ty));
1900 if (Ty == Ice::IceType_i1)
1901 return 1;
1902 return Ice::typeWidthInBytes(Ty) * CHAR_BIT;
1903 }
1904
1905 /// Returns true iff a bitcast from SourceType to TargetType is allowed.
1906 static bool isBitcastValid(Ice::Type SourceType, Ice::Type TargetType) {
1907 return bitcastSizeInBits(SourceType) == bitcastSizeInBits(TargetType);
1908 }
1909
Andrew Scull57e12682015-09-16 11:30:19 -07001910 /// Returns true iff the NaCl bitcode Opcode is a valid cast opcode for
1911 /// converting SourceType to TargetType. Updates CastKind to the corresponding
1912 /// instruction cast opcode. Also generates an error message when this
1913 /// function returns false.
Karl Schimpfbf170372014-12-15 10:16:31 -08001914 bool convertCastOpToIceOp(uint64_t Opcode, Ice::Type SourceType,
1915 Ice::Type TargetType,
1916 Ice::InstCast::OpKind &CastKind) {
1917 bool Result;
1918 switch (Opcode) {
1919 default: {
1920 std::string Buffer;
1921 raw_string_ostream StrBuf(Buffer);
1922 StrBuf << "Cast opcode " << Opcode << " not understood.\n";
1923 Error(StrBuf.str());
Karl Schimpfbf170372014-12-15 10:16:31 -08001924 CastKind = Ice::InstCast::Bitcast;
1925 return false;
1926 }
1927 case naclbitc::CAST_TRUNC:
1928 CastKind = Ice::InstCast::Trunc;
1929 Result = isIntTruncCastValid(SourceType, TargetType);
1930 break;
1931 case naclbitc::CAST_ZEXT:
1932 CastKind = Ice::InstCast::Zext;
1933 Result = isIntExtCastValid(SourceType, TargetType);
1934 break;
1935 case naclbitc::CAST_SEXT:
1936 CastKind = Ice::InstCast::Sext;
1937 Result = isIntExtCastValid(SourceType, TargetType);
1938 break;
1939 case naclbitc::CAST_FPTOUI:
1940 CastKind = Ice::InstCast::Fptoui;
1941 Result = isFloatToIntCastValid(SourceType, TargetType);
1942 break;
1943 case naclbitc::CAST_FPTOSI:
1944 CastKind = Ice::InstCast::Fptosi;
1945 Result = isFloatToIntCastValid(SourceType, TargetType);
1946 break;
1947 case naclbitc::CAST_UITOFP:
1948 CastKind = Ice::InstCast::Uitofp;
1949 Result = isIntToFloatCastValid(SourceType, TargetType);
1950 break;
1951 case naclbitc::CAST_SITOFP:
1952 CastKind = Ice::InstCast::Sitofp;
1953 Result = isIntToFloatCastValid(SourceType, TargetType);
1954 break;
1955 case naclbitc::CAST_FPTRUNC:
1956 CastKind = Ice::InstCast::Fptrunc;
1957 Result = isFloatTruncCastValid(SourceType, TargetType);
1958 break;
1959 case naclbitc::CAST_FPEXT:
1960 CastKind = Ice::InstCast::Fpext;
1961 Result = isFloatExtCastValid(SourceType, TargetType);
1962 break;
1963 case naclbitc::CAST_BITCAST:
1964 CastKind = Ice::InstCast::Bitcast;
1965 Result = isBitcastValid(SourceType, TargetType);
1966 break;
1967 }
1968 if (!Result) {
1969 std::string Buffer;
1970 raw_string_ostream StrBuf(Buffer);
1971 StrBuf << "Illegal cast: " << Ice::InstCast::getCastName(CastKind) << " "
1972 << SourceType << " to " << TargetType;
1973 Error(StrBuf.str());
1974 }
1975 return Result;
1976 }
1977
Andrew Scull57e12682015-09-16 11:30:19 -07001978 // Converts PNaCl bitcode Icmp operator to corresponding ICE op. Returns true
1979 // if able to convert, false otherwise.
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07001980 bool convertNaClBitcICmpOpToIce(uint64_t Op,
1981 Ice::InstIcmp::ICond &Cond) const {
1982 switch (Op) {
1983 case naclbitc::ICMP_EQ:
1984 Cond = Ice::InstIcmp::Eq;
1985 return true;
1986 case naclbitc::ICMP_NE:
1987 Cond = Ice::InstIcmp::Ne;
1988 return true;
1989 case naclbitc::ICMP_UGT:
1990 Cond = Ice::InstIcmp::Ugt;
1991 return true;
1992 case naclbitc::ICMP_UGE:
1993 Cond = Ice::InstIcmp::Uge;
1994 return true;
1995 case naclbitc::ICMP_ULT:
1996 Cond = Ice::InstIcmp::Ult;
1997 return true;
1998 case naclbitc::ICMP_ULE:
1999 Cond = Ice::InstIcmp::Ule;
2000 return true;
2001 case naclbitc::ICMP_SGT:
2002 Cond = Ice::InstIcmp::Sgt;
2003 return true;
2004 case naclbitc::ICMP_SGE:
2005 Cond = Ice::InstIcmp::Sge;
2006 return true;
2007 case naclbitc::ICMP_SLT:
2008 Cond = Ice::InstIcmp::Slt;
2009 return true;
2010 case naclbitc::ICMP_SLE:
2011 Cond = Ice::InstIcmp::Sle;
2012 return true;
2013 default:
Jim Stichnothdddaf9c2014-12-04 14:09:21 -08002014 // Make sure Cond is always initialized.
2015 Cond = static_cast<Ice::InstIcmp::ICond>(0);
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002016 return false;
2017 }
2018 }
2019
Andrew Scull57e12682015-09-16 11:30:19 -07002020 // Converts PNaCl bitcode Fcmp operator to corresponding ICE op. Returns true
2021 // if able to convert, false otherwise.
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002022 bool convertNaClBitcFCompOpToIce(uint64_t Op,
2023 Ice::InstFcmp::FCond &Cond) const {
2024 switch (Op) {
2025 case naclbitc::FCMP_FALSE:
2026 Cond = Ice::InstFcmp::False;
2027 return true;
2028 case naclbitc::FCMP_OEQ:
2029 Cond = Ice::InstFcmp::Oeq;
2030 return true;
2031 case naclbitc::FCMP_OGT:
2032 Cond = Ice::InstFcmp::Ogt;
2033 return true;
2034 case naclbitc::FCMP_OGE:
2035 Cond = Ice::InstFcmp::Oge;
2036 return true;
2037 case naclbitc::FCMP_OLT:
2038 Cond = Ice::InstFcmp::Olt;
2039 return true;
2040 case naclbitc::FCMP_OLE:
2041 Cond = Ice::InstFcmp::Ole;
2042 return true;
2043 case naclbitc::FCMP_ONE:
2044 Cond = Ice::InstFcmp::One;
2045 return true;
2046 case naclbitc::FCMP_ORD:
2047 Cond = Ice::InstFcmp::Ord;
2048 return true;
2049 case naclbitc::FCMP_UNO:
2050 Cond = Ice::InstFcmp::Uno;
2051 return true;
2052 case naclbitc::FCMP_UEQ:
2053 Cond = Ice::InstFcmp::Ueq;
2054 return true;
2055 case naclbitc::FCMP_UGT:
2056 Cond = Ice::InstFcmp::Ugt;
2057 return true;
2058 case naclbitc::FCMP_UGE:
2059 Cond = Ice::InstFcmp::Uge;
2060 return true;
2061 case naclbitc::FCMP_ULT:
2062 Cond = Ice::InstFcmp::Ult;
2063 return true;
2064 case naclbitc::FCMP_ULE:
2065 Cond = Ice::InstFcmp::Ule;
2066 return true;
2067 case naclbitc::FCMP_UNE:
2068 Cond = Ice::InstFcmp::Une;
2069 return true;
2070 case naclbitc::FCMP_TRUE:
2071 Cond = Ice::InstFcmp::True;
2072 return true;
2073 default:
Jim Stichnothdddaf9c2014-12-04 14:09:21 -08002074 // Make sure Cond is always initialized.
2075 Cond = static_cast<Ice::InstFcmp::FCond>(0);
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002076 return false;
2077 }
2078 }
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002079
Andrew Scull57e12682015-09-16 11:30:19 -07002080 // Creates an error instruction, generating a value of type Ty, and adds a
2081 // placeholder so that instruction indices line up. Some instructions, such
2082 // as a call, will not generate a value if the return type is void. In such
2083 // cases, a placeholder value for the badly formed instruction is not needed.
2084 // Hence, if Ty is void, an error instruction is not appended.
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002085 void appendErrorInstruction(Ice::Type Ty) {
Andrew Scull57e12682015-09-16 11:30:19 -07002086 // Note: we don't worry about downstream translation errors because the
2087 // function will not be translated if any errors occur.
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002088 if (Ty == Ice::IceType_void)
2089 return;
2090 Ice::Variable *Var = getNextInstVar(Ty);
Jim Stichnoth8e928382015-02-02 17:03:08 -08002091 CurrentNode->appendInst(Ice::InstAssign::create(Func.get(), Var, Var));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002092 }
Karl Schimpf9d25e622015-09-16 13:47:01 -07002093
2094 Ice::Operand *reportGetOperandUndefined(NaClBcIndexSize_t Index) {
2095 std::string Buffer;
2096 raw_string_ostream StrBuf(Buffer);
2097 StrBuf << "Value index " << Index << " not defined!";
Karl Schimpf43632b92015-09-21 15:32:30 -07002098 Error(StrBuf.str());
2099 // Recover and return some value.
2100 if (!LocalOperands.empty())
2101 return LocalOperands.front();
2102 return Context->getGlobalConstantByID(0);
Karl Schimpf9d25e622015-09-16 13:47:01 -07002103 }
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002104
Jim Stichnoth48e3ae52015-10-01 13:33:35 -07002105 void verifyCallArgTypeMatches(Ice::FunctionDeclaration *Fcn, Ice::SizeT Index,
2106 Ice::Type ArgType, Ice::Type ParamType) {
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002107 if (ArgType != ParamType) {
2108 std::string Buffer;
2109 raw_string_ostream StrBuf(Buffer);
Jim Stichnoth48e3ae52015-10-01 13:33:35 -07002110 StrBuf << "Argument " << (Index + 1) << " of " << printName(Fcn)
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002111 << " expects " << ParamType << ". Found: " << ArgType;
2112 Error(StrBuf.str());
2113 }
2114 }
2115
Jim Stichnoth467ffe52016-03-29 15:01:06 -07002116 const std::string printName(Ice::FunctionDeclaration *Fcn) {
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002117 if (Fcn)
Jim Stichnoth467ffe52016-03-29 15:01:06 -07002118 return Fcn->getName().toString();
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002119 return "function";
2120 }
Karl Schimpfd6064a12014-08-27 15:34:58 -07002121};
2122
Karl Schimpfd6064a12014-08-27 15:34:58 -07002123void FunctionParser::ExitBlock() {
Karl Schimpf6c17dd82015-06-30 10:25:27 -07002124 // Check if the last instruction in the function was terminating.
2125 if (!InstIsTerminating) {
2126 Error("Last instruction in function not terminator");
Karl Schimpf6c17dd82015-06-30 10:25:27 -07002127 // Recover by inserting an unreachable instruction.
2128 CurrentNode->appendInst(Ice::InstUnreachable::create(Func.get()));
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002129 }
Karl Schimpf98ed4462015-08-14 13:08:42 -07002130 ++CurrentBbIndex;
2131 if (CurrentBbIndex != DeclaredNumberBbs) {
2132 std::string Buffer;
2133 raw_string_ostream StrBuf(Buffer);
2134 StrBuf << "Function declared " << DeclaredNumberBbs
2135 << " basic blocks, but defined " << CurrentBbIndex << ".";
2136 Error(StrBuf.str());
2137 }
Andrew Scull57e12682015-09-16 11:30:19 -07002138 // Before translating, check for blocks without instructions, and insert
2139 // unreachable. This shouldn't happen, but be safe.
Karl Schimpf74cd8832015-06-23 11:05:01 -07002140 size_t Index = 0;
Jim Stichnothf44f3712014-10-01 14:05:51 -07002141 for (Ice::CfgNode *Node : Func->getNodes()) {
Jim Stichnothbfb410d2014-11-05 16:04:05 -08002142 if (Node->getInsts().empty()) {
Karl Schimpfd6064a12014-08-27 15:34:58 -07002143 std::string Buffer;
2144 raw_string_ostream StrBuf(Buffer);
2145 StrBuf << "Basic block " << Index << " contains no instructions";
2146 Error(StrBuf.str());
Jim Stichnoth8e928382015-02-02 17:03:08 -08002147 Node->appendInst(Ice::InstUnreachable::create(Func.get()));
Karl Schimpfd6064a12014-08-27 15:34:58 -07002148 }
Jim Stichnothf44f3712014-10-01 14:05:51 -07002149 ++Index;
Karl Schimpfd6064a12014-08-27 15:34:58 -07002150 }
Jim Stichnoth69d3f9c2015-03-23 10:33:38 -07002151 Func->computeInOutEdges();
Karl Schimpfd6064a12014-08-27 15:34:58 -07002152}
2153
Karl Schimpf74cd8832015-06-23 11:05:01 -07002154void FunctionParser::reportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op,
Karl Schimpfd6064a12014-08-27 15:34:58 -07002155 Ice::Type OpTy) {
2156 std::string Buffer;
2157 raw_string_ostream StrBuf(Buffer);
2158 StrBuf << "Invalid operator type for " << Ice::InstArithmetic::getOpName(Op)
2159 << ". Found " << OpTy;
2160 Error(StrBuf.str());
2161}
2162
2163void FunctionParser::ProcessRecord() {
Andrew Scull57e12682015-09-16 11:30:19 -07002164 // Note: To better separate parse/IR generation times, when IR generation is
2165 // disabled we do the following:
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002166 // 1) Delay exiting until after we extract operands.
2167 // 2) return before we access operands, since all operands will be a nullptr.
Karl Schimpfd6064a12014-08-27 15:34:58 -07002168 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
2169 if (InstIsTerminating) {
2170 InstIsTerminating = false;
Karl Schimpf98ed4462015-08-14 13:08:42 -07002171 ++CurrentBbIndex;
Jim Stichnoth0d4fc922015-12-13 21:36:33 -08002172 CurrentNode = getBasicBlock(CurrentBbIndex);
Karl Schimpfd6064a12014-08-27 15:34:58 -07002173 }
Karl Schimpf47661562014-09-11 14:42:49 -07002174 // The base index for relative indexing.
Karl Schimpf74cd8832015-06-23 11:05:01 -07002175 NaClBcIndexSize_t BaseIndex = getNextInstIndex();
Karl Schimpfd6064a12014-08-27 15:34:58 -07002176 switch (Record.GetCode()) {
2177 case naclbitc::FUNC_CODE_DECLAREBLOCKS: {
2178 // DECLAREBLOCKS: [n]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002179 if (!isValidRecordSize(1, "count"))
Karl Schimpfc0fdc272014-09-02 10:47:28 -07002180 return;
Karl Schimpf98ed4462015-08-14 13:08:42 -07002181 if (DeclaredNumberBbs > 0) {
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002182 Error("Duplicate function block count record");
2183 return;
2184 }
Karl Schimpf98ed4462015-08-14 13:08:42 -07002185
Karl Schimpf98ed4462015-08-14 13:08:42 -07002186 // Check for bad large sizes, since they can make ridiculous memory
Karl Schimpf7a993272015-08-17 12:43:29 -07002187 // requests and hang the user for large amounts of time.
2188 uint64_t NumBbs = Values[0];
2189 if (NumBbs > MaxRecordsInBlock) {
Karl Schimpf98ed4462015-08-14 13:08:42 -07002190 std::string Buffer;
2191 raw_string_ostream StrBuf(Buffer);
2192 StrBuf << "Function defines " << NumBbs
2193 << " basic blocks, which is too big for a function containing "
2194 << NumBytesDefiningFunction << " bytes";
2195 Error(StrBuf.str());
Karl Schimpf7a993272015-08-17 12:43:29 -07002196 NumBbs = MaxRecordsInBlock;
Karl Schimpf98ed4462015-08-14 13:08:42 -07002197 }
2198
2199 if (NumBbs == 0) {
2200 Error("Functions must contain at least one basic block.");
2201 NumBbs = 1;
2202 }
2203
2204 DeclaredNumberBbs = NumBbs;
Karl Schimpf98ed4462015-08-14 13:08:42 -07002205 // Install the basic blocks, skipping bb0 which was created in the
2206 // constructor.
2207 for (size_t i = 1; i < NumBbs; ++i)
2208 installNextBasicBlock();
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002209 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -07002210 }
2211 case naclbitc::FUNC_CODE_INST_BINOP: {
Karl Schimpfe73ee852016-03-25 07:12:26 -07002212 // Note: Old bitcode files may have an additional 'flags' operand, which is
2213 // ignored.
2214
2215 // BINOP: [opval, opval, opcode, [flags]]
2216
2217 if (!isValidRecordSizeInRange(3, 4, "binop"))
Karl Schimpfc0fdc272014-09-02 10:47:28 -07002218 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002219 Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex);
2220 Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex);
Karl Schimpfd6064a12014-08-27 15:34:58 -07002221 Ice::Type Type1 = Op1->getType();
2222 Ice::Type Type2 = Op2->getType();
2223 if (Type1 != Type2) {
2224 std::string Buffer;
2225 raw_string_ostream StrBuf(Buffer);
2226 StrBuf << "Binop argument types differ: " << Type1 << " and " << Type2;
2227 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002228 appendErrorInstruction(Type1);
2229 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -07002230 }
2231
2232 Ice::InstArithmetic::OpKind Opcode;
Karl Schimpf9bb188d2014-12-10 12:54:34 -08002233 if (!convertBinopOpcode(Values[2], Type1, Opcode)) {
2234 appendErrorInstruction(Type1);
Karl Schimpfc0fdc272014-09-02 10:47:28 -07002235 return;
Karl Schimpf9bb188d2014-12-10 12:54:34 -08002236 }
Karl Schimpf47661562014-09-11 14:42:49 -07002237 CurrentNode->appendInst(Ice::InstArithmetic::create(
Jim Stichnoth8e928382015-02-02 17:03:08 -08002238 Func.get(), Opcode, getNextInstVar(Type1), Op1, Op2));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002239 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -07002240 }
Karl Schimpfc0fdc272014-09-02 10:47:28 -07002241 case naclbitc::FUNC_CODE_INST_CAST: {
2242 // CAST: [opval, destty, castopc]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002243 if (!isValidRecordSize(3, "cast"))
Karl Schimpfc0fdc272014-09-02 10:47:28 -07002244 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002245 Ice::Operand *Src = getRelativeOperand(Values[0], BaseIndex);
Karl Schimpf645aa1a2014-10-08 09:05:53 -07002246 Ice::Type CastType = Context->getSimpleTypeByID(Values[1]);
Karl Schimpfc0fdc272014-09-02 10:47:28 -07002247 Ice::InstCast::OpKind CastKind;
Karl Schimpfbf170372014-12-15 10:16:31 -08002248 if (!convertCastOpToIceOp(Values[2], Src->getType(), CastType, CastKind)) {
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002249 appendErrorInstruction(CastType);
Karl Schimpfc0fdc272014-09-02 10:47:28 -07002250 return;
2251 }
Jim Stichnoth8e928382015-02-02 17:03:08 -08002252 CurrentNode->appendInst(Ice::InstCast::create(
2253 Func.get(), CastKind, getNextInstVar(CastType), Src));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002254 return;
Karl Schimpfc0fdc272014-09-02 10:47:28 -07002255 }
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07002256 case naclbitc::FUNC_CODE_INST_VSELECT: {
2257 // VSELECT: [opval, opval, pred]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002258 if (!isValidRecordSize(3, "select"))
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002259 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002260 Ice::Operand *ThenVal = getRelativeOperand(Values[0], BaseIndex);
Karl Schimpf47661562014-09-11 14:42:49 -07002261 Ice::Operand *ElseVal = getRelativeOperand(Values[1], BaseIndex);
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002262 Ice::Operand *CondVal = getRelativeOperand(Values[2], BaseIndex);
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002263 Ice::Type ThenType = ThenVal->getType();
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07002264 Ice::Type ElseType = ElseVal->getType();
2265 if (ThenType != ElseType) {
2266 std::string Buffer;
2267 raw_string_ostream StrBuf(Buffer);
2268 StrBuf << "Select operands not same type. Found " << ThenType << " and "
2269 << ElseType;
2270 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002271 appendErrorInstruction(ThenType);
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07002272 return;
2273 }
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07002274 Ice::Type CondType = CondVal->getType();
2275 if (isVectorType(CondType)) {
2276 if (!isVectorType(ThenType) ||
2277 typeElementType(CondType) != Ice::IceType_i1 ||
2278 typeNumElements(ThenType) != typeNumElements(CondType)) {
2279 std::string Buffer;
2280 raw_string_ostream StrBuf(Buffer);
Karl Schimpf97501832014-09-16 13:35:32 -07002281 StrBuf << "Select condition type " << CondType
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07002282 << " not allowed for values of type " << ThenType;
2283 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002284 appendErrorInstruction(ThenType);
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07002285 return;
2286 }
2287 } else if (CondVal->getType() != Ice::IceType_i1) {
2288 std::string Buffer;
2289 raw_string_ostream StrBuf(Buffer);
Jim Stichnothdd842db2015-01-27 12:53:53 -08002290 StrBuf << "Select condition " << CondVal
2291 << " not type i1. Found: " << CondVal->getType();
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07002292 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002293 appendErrorInstruction(ThenType);
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07002294 return;
2295 }
Karl Schimpf47661562014-09-11 14:42:49 -07002296 CurrentNode->appendInst(Ice::InstSelect::create(
Jim Stichnoth8e928382015-02-02 17:03:08 -08002297 Func.get(), getNextInstVar(ThenType), CondVal, ThenVal, ElseVal));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002298 return;
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07002299 }
Karl Schimpf71ba8222014-09-03 09:46:24 -07002300 case naclbitc::FUNC_CODE_INST_EXTRACTELT: {
2301 // EXTRACTELT: [opval, opval]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002302 if (!isValidRecordSize(2, "extract element"))
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002303 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002304 Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex);
Karl Schimpf47661562014-09-11 14:42:49 -07002305 Ice::Operand *Index = getRelativeOperand(Values[1], BaseIndex);
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002306 Ice::Type VecType = Vec->getType();
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002307 VectorIndexCheckValue IndexCheckValue = validateVectorIndex(Vec, Index);
2308 if (IndexCheckValue != VectorIndexValid) {
Karl Schimpf71ba8222014-09-03 09:46:24 -07002309 std::string Buffer;
2310 raw_string_ostream StrBuf(Buffer);
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002311 dumpVectorIndexCheckValue(StrBuf, IndexCheckValue);
2312 StrBuf << ": extractelement " << VecType << " " << *Vec << ", "
2313 << Index->getType() << " " << *Index;
Karl Schimpf71ba8222014-09-03 09:46:24 -07002314 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002315 appendErrorInstruction(VecType);
2316 return;
Karl Schimpf71ba8222014-09-03 09:46:24 -07002317 }
Karl Schimpf47661562014-09-11 14:42:49 -07002318 CurrentNode->appendInst(Ice::InstExtractElement::create(
Jim Stichnoth8e928382015-02-02 17:03:08 -08002319 Func.get(), getNextInstVar(typeElementType(VecType)), Vec, Index));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002320 return;
Karl Schimpf71ba8222014-09-03 09:46:24 -07002321 }
2322 case naclbitc::FUNC_CODE_INST_INSERTELT: {
2323 // INSERTELT: [opval, opval, opval]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002324 if (!isValidRecordSize(3, "insert element"))
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002325 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002326 Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex);
Karl Schimpf47661562014-09-11 14:42:49 -07002327 Ice::Operand *Elt = getRelativeOperand(Values[1], BaseIndex);
Karl Schimpf47661562014-09-11 14:42:49 -07002328 Ice::Operand *Index = getRelativeOperand(Values[2], BaseIndex);
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002329 Ice::Type VecType = Vec->getType();
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002330 VectorIndexCheckValue IndexCheckValue = validateVectorIndex(Vec, Index);
2331 if (IndexCheckValue != VectorIndexValid) {
Karl Schimpf71ba8222014-09-03 09:46:24 -07002332 std::string Buffer;
2333 raw_string_ostream StrBuf(Buffer);
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002334 dumpVectorIndexCheckValue(StrBuf, IndexCheckValue);
2335 StrBuf << ": insertelement " << VecType << " " << *Vec << ", "
2336 << Elt->getType() << " " << *Elt << ", " << Index->getType() << " "
2337 << *Index;
Karl Schimpf71ba8222014-09-03 09:46:24 -07002338 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002339 appendErrorInstruction(Elt->getType());
2340 return;
Karl Schimpf71ba8222014-09-03 09:46:24 -07002341 }
Karl Schimpf43632b92015-09-21 15:32:30 -07002342 if (Ice::typeElementType(VecType) != Elt->getType()) {
2343 std::string Buffer;
2344 raw_string_ostream StrBuf(Buffer);
2345 StrBuf << "Insertelement: Element type "
2346 << Ice::typeString(Elt->getType()) << " doesn't match vector type "
2347 << Ice::typeString(VecType);
2348 Error(StrBuf.str());
2349 appendErrorInstruction(Elt->getType());
2350 return;
2351 }
Karl Schimpf47661562014-09-11 14:42:49 -07002352 CurrentNode->appendInst(Ice::InstInsertElement::create(
Jim Stichnoth8e928382015-02-02 17:03:08 -08002353 Func.get(), getNextInstVar(VecType), Vec, Elt, Index));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002354 return;
Karl Schimpf71ba8222014-09-03 09:46:24 -07002355 }
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002356 case naclbitc::FUNC_CODE_INST_CMP2: {
2357 // CMP2: [opval, opval, pred]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002358 if (!isValidRecordSize(3, "compare"))
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002359 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002360 Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex);
2361 Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex);
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002362 Ice::Type Op1Type = Op1->getType();
2363 Ice::Type Op2Type = Op2->getType();
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002364 Ice::Type DestType = getCompareResultType(Op1Type);
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002365 if (Op1Type != Op2Type) {
2366 std::string Buffer;
2367 raw_string_ostream StrBuf(Buffer);
Jim Stichnothdd842db2015-01-27 12:53:53 -08002368 StrBuf << "Compare argument types differ: " << Op1Type << " and "
2369 << Op2Type;
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002370 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002371 appendErrorInstruction(DestType);
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002372 Op2 = Op1;
2373 }
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002374 if (DestType == Ice::IceType_void) {
2375 std::string Buffer;
2376 raw_string_ostream StrBuf(Buffer);
2377 StrBuf << "Compare not defined for type " << Op1Type;
2378 Error(StrBuf.str());
2379 return;
2380 }
Karl Schimpf47661562014-09-11 14:42:49 -07002381 Ice::Variable *Dest = getNextInstVar(DestType);
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002382 if (isIntegerType(Op1Type)) {
2383 Ice::InstIcmp::ICond Cond;
2384 if (!convertNaClBitcICmpOpToIce(Values[2], Cond)) {
2385 std::string Buffer;
2386 raw_string_ostream StrBuf(Buffer);
2387 StrBuf << "Compare record contains unknown integer predicate index: "
2388 << Values[2];
2389 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002390 appendErrorInstruction(DestType);
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002391 }
Karl Schimpf47661562014-09-11 14:42:49 -07002392 CurrentNode->appendInst(
Jim Stichnoth8e928382015-02-02 17:03:08 -08002393 Ice::InstIcmp::create(Func.get(), Cond, Dest, Op1, Op2));
Jim Stichnothdd842db2015-01-27 12:53:53 -08002394 } else if (isFloatingType(Op1Type)) {
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002395 Ice::InstFcmp::FCond Cond;
2396 if (!convertNaClBitcFCompOpToIce(Values[2], Cond)) {
2397 std::string Buffer;
2398 raw_string_ostream StrBuf(Buffer);
2399 StrBuf << "Compare record contains unknown float predicate index: "
2400 << Values[2];
2401 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002402 appendErrorInstruction(DestType);
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002403 }
Karl Schimpf47661562014-09-11 14:42:49 -07002404 CurrentNode->appendInst(
Jim Stichnoth8e928382015-02-02 17:03:08 -08002405 Ice::InstFcmp::create(Func.get(), Cond, Dest, Op1, Op2));
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002406 } else {
2407 // Not sure this can happen, but be safe.
2408 std::string Buffer;
2409 raw_string_ostream StrBuf(Buffer);
2410 StrBuf << "Compare on type not understood: " << Op1Type;
2411 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002412 appendErrorInstruction(DestType);
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002413 return;
2414 }
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002415 return;
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002416 }
Karl Schimpfd6064a12014-08-27 15:34:58 -07002417 case naclbitc::FUNC_CODE_INST_RET: {
2418 // RET: [opval?]
Karl Schimpf6c17dd82015-06-30 10:25:27 -07002419 InstIsTerminating = true;
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002420 if (!isValidRecordSizeInRange(0, 1, "return"))
Karl Schimpfc0fdc272014-09-02 10:47:28 -07002421 return;
Jim Stichnothbfb410d2014-11-05 16:04:05 -08002422 if (Values.empty()) {
Jim Stichnoth8e928382015-02-02 17:03:08 -08002423 CurrentNode->appendInst(Ice::InstRet::create(Func.get()));
Karl Schimpfd6064a12014-08-27 15:34:58 -07002424 } else {
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002425 Ice::Operand *RetVal = getRelativeOperand(Values[0], BaseIndex);
Jim Stichnoth8e928382015-02-02 17:03:08 -08002426 CurrentNode->appendInst(Ice::InstRet::create(Func.get(), RetVal));
Karl Schimpfd6064a12014-08-27 15:34:58 -07002427 }
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002428 return;
Karl Schimpfc836acb2014-09-05 08:32:47 -07002429 }
2430 case naclbitc::FUNC_CODE_INST_BR: {
Karl Schimpf6c17dd82015-06-30 10:25:27 -07002431 InstIsTerminating = true;
Karl Schimpfc836acb2014-09-05 08:32:47 -07002432 if (Values.size() == 1) {
2433 // BR: [bb#]
2434 Ice::CfgNode *Block = getBranchBasicBlock(Values[0]);
Karl Schimpfe3f64d02014-10-07 10:38:22 -07002435 if (Block == nullptr)
Karl Schimpfc836acb2014-09-05 08:32:47 -07002436 return;
Jim Stichnoth8e928382015-02-02 17:03:08 -08002437 CurrentNode->appendInst(Ice::InstBr::create(Func.get(), Block));
Karl Schimpfc836acb2014-09-05 08:32:47 -07002438 } else {
2439 // BR: [bb#, bb#, opval]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002440 if (!isValidRecordSize(3, "branch"))
Karl Schimpfc836acb2014-09-05 08:32:47 -07002441 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002442 Ice::Operand *Cond = getRelativeOperand(Values[2], BaseIndex);
Karl Schimpfc836acb2014-09-05 08:32:47 -07002443 if (Cond->getType() != Ice::IceType_i1) {
2444 std::string Buffer;
2445 raw_string_ostream StrBuf(Buffer);
Jim Stichnothdd842db2015-01-27 12:53:53 -08002446 StrBuf << "Branch condition " << *Cond
2447 << " not i1. Found: " << Cond->getType();
Karl Schimpfc836acb2014-09-05 08:32:47 -07002448 Error(StrBuf.str());
2449 return;
2450 }
2451 Ice::CfgNode *ThenBlock = getBranchBasicBlock(Values[0]);
2452 Ice::CfgNode *ElseBlock = getBranchBasicBlock(Values[1]);
Karl Schimpfe3f64d02014-10-07 10:38:22 -07002453 if (ThenBlock == nullptr || ElseBlock == nullptr)
Karl Schimpfc836acb2014-09-05 08:32:47 -07002454 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002455 CurrentNode->appendInst(
Jim Stichnoth8e928382015-02-02 17:03:08 -08002456 Ice::InstBr::create(Func.get(), Cond, ThenBlock, ElseBlock));
Karl Schimpfc836acb2014-09-05 08:32:47 -07002457 }
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002458 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -07002459 }
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002460 case naclbitc::FUNC_CODE_INST_SWITCH: {
2461 // SWITCH: [Condty, Cond, BbIndex, NumCases Case ...]
2462 // where Case = [1, 1, Value, BbIndex].
2463 //
Andrew Scull57e12682015-09-16 11:30:19 -07002464 // Note: Unlike most instructions, we don't infer the type of Cond, but
2465 // provide it as a separate field. There are also unnecessary data fields
2466 // (i.e. constants 1). These were not cleaned up in PNaCl bitcode because
2467 // the bitcode format was already frozen when the problem was noticed.
Karl Schimpf6c17dd82015-06-30 10:25:27 -07002468 InstIsTerminating = true;
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002469 if (!isValidRecordSizeAtLeast(4, "switch"))
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002470 return;
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002471
Karl Schimpf645aa1a2014-10-08 09:05:53 -07002472 Ice::Type CondTy = Context->getSimpleTypeByID(Values[0]);
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002473 if (!Ice::isScalarIntegerType(CondTy)) {
2474 std::string Buffer;
2475 raw_string_ostream StrBuf(Buffer);
2476 StrBuf << "Case condition must be non-wide integer. Found: " << CondTy;
2477 Error(StrBuf.str());
2478 return;
2479 }
2480 Ice::SizeT BitWidth = Ice::getScalarIntBitWidth(CondTy);
2481 Ice::Operand *Cond = getRelativeOperand(Values[1], BaseIndex);
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002482
Jim Stichnoth0d4fc922015-12-13 21:36:33 -08002483 if (CondTy != Cond->getType()) {
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002484 std::string Buffer;
2485 raw_string_ostream StrBuf(Buffer);
2486 StrBuf << "Case condition expects type " << CondTy
2487 << ". Found: " << Cond->getType();
2488 Error(StrBuf.str());
2489 return;
2490 }
Jim Stichnoth0d4fc922015-12-13 21:36:33 -08002491 Ice::CfgNode *DefaultLabel = getBranchBasicBlock(Values[2]);
Karl Schimpf0042fea2015-08-21 09:41:01 -07002492 if (DefaultLabel == nullptr)
2493 return;
Karl Schimpf74cd8832015-06-23 11:05:01 -07002494 uint64_t NumCasesRaw = Values[3];
2495 if (NumCasesRaw > std::numeric_limits<uint32_t>::max()) {
2496 std::string Buffer;
2497 raw_string_ostream StrBuf(Buffer);
2498 StrBuf << "Too many cases specified in switch: " << NumCasesRaw;
2499 Error(StrBuf.str());
2500 NumCasesRaw = std::numeric_limits<uint32_t>::max();
2501 }
2502 uint32_t NumCases = NumCasesRaw;
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002503
2504 // Now recognize each of the cases.
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002505 if (!isValidRecordSize(4 + NumCases * 4, "switch"))
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002506 return;
Karl Schimpf0042fea2015-08-21 09:41:01 -07002507 std::unique_ptr<Ice::InstSwitch> Switch(
Jim Stichnoth0d4fc922015-12-13 21:36:33 -08002508 Ice::InstSwitch::create(Func.get(), NumCases, Cond, DefaultLabel));
Jim Stichnothdd842db2015-01-27 12:53:53 -08002509 unsigned ValCaseIndex = 4; // index to beginning of case entry.
Karl Schimpf74cd8832015-06-23 11:05:01 -07002510 for (uint32_t CaseIndex = 0; CaseIndex < NumCases;
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002511 ++CaseIndex, ValCaseIndex += 4) {
Jim Stichnothdd842db2015-01-27 12:53:53 -08002512 if (Values[ValCaseIndex] != 1 || Values[ValCaseIndex + 1] != 1) {
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002513 std::string Buffer;
2514 raw_string_ostream StrBuf(Buffer);
2515 StrBuf << "Sequence [1, 1, value, label] expected for case entry "
2516 << "in switch record. (at index" << ValCaseIndex << ")";
2517 Error(StrBuf.str());
2518 return;
2519 }
Karl Schimpfa5295b02015-12-01 11:24:53 -08002520 BitcodeInt Value(BitWidth,
Karl Schimpf32817482014-12-15 09:52:26 -08002521 NaClDecodeSignRotatedValue(Values[ValCaseIndex + 2]));
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002522 Ice::CfgNode *Label = getBranchBasicBlock(Values[ValCaseIndex + 3]);
Karl Schimpf0042fea2015-08-21 09:41:01 -07002523 if (Label == nullptr)
2524 return;
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002525 Switch->addBranch(CaseIndex, Value.getSExtValue(), Label);
2526 }
Karl Schimpf0042fea2015-08-21 09:41:01 -07002527 CurrentNode->appendInst(Switch.release());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002528 return;
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002529 }
Karl Schimpf97501832014-09-16 13:35:32 -07002530 case naclbitc::FUNC_CODE_INST_UNREACHABLE: {
2531 // UNREACHABLE: []
Karl Schimpf6c17dd82015-06-30 10:25:27 -07002532 InstIsTerminating = true;
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002533 if (!isValidRecordSize(0, "unreachable"))
Karl Schimpf97501832014-09-16 13:35:32 -07002534 return;
Jim Stichnoth8e928382015-02-02 17:03:08 -08002535 CurrentNode->appendInst(Ice::InstUnreachable::create(Func.get()));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002536 return;
Karl Schimpf97501832014-09-16 13:35:32 -07002537 }
Karl Schimpf47661562014-09-11 14:42:49 -07002538 case naclbitc::FUNC_CODE_INST_PHI: {
2539 // PHI: [ty, val1, bb1, ..., valN, bbN] for n >= 2.
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002540 if (!isValidRecordSizeAtLeast(3, "phi"))
Karl Schimpf47661562014-09-11 14:42:49 -07002541 return;
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002542 Ice::Type Ty = Context->getSimpleTypeByID(Values[0]);
Karl Schimpf47661562014-09-11 14:42:49 -07002543 if ((Values.size() & 0x1) == 0) {
2544 // Not an odd number of values.
2545 std::string Buffer;
2546 raw_string_ostream StrBuf(Buffer);
2547 StrBuf << "function block phi record size not valid: " << Values.size();
2548 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002549 appendErrorInstruction(Ty);
Karl Schimpf47661562014-09-11 14:42:49 -07002550 return;
2551 }
Karl Schimpf47661562014-09-11 14:42:49 -07002552 if (Ty == Ice::IceType_void) {
2553 Error("Phi record using type void not allowed");
2554 return;
2555 }
2556 Ice::Variable *Dest = getNextInstVar(Ty);
Jim Stichnoth8e928382015-02-02 17:03:08 -08002557 Ice::InstPhi *Phi =
2558 Ice::InstPhi::create(Func.get(), Values.size() >> 1, Dest);
Karl Schimpf74cd8832015-06-23 11:05:01 -07002559 for (size_t i = 1; i < Values.size(); i += 2) {
Karl Schimpf47661562014-09-11 14:42:49 -07002560 Ice::Operand *Op =
2561 getRelativeOperand(NaClDecodeSignRotatedValue(Values[i]), BaseIndex);
2562 if (Op->getType() != Ty) {
2563 std::string Buffer;
2564 raw_string_ostream StrBuf(Buffer);
Karl Schimpf97501832014-09-16 13:35:32 -07002565 StrBuf << "Value " << *Op << " not type " << Ty
2566 << " in phi instruction. Found: " << Op->getType();
Karl Schimpf47661562014-09-11 14:42:49 -07002567 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002568 appendErrorInstruction(Ty);
Karl Schimpf47661562014-09-11 14:42:49 -07002569 return;
2570 }
2571 Phi->addArgument(Op, getBasicBlock(Values[i + 1]));
2572 }
2573 CurrentNode->appendInst(Phi);
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002574 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002575 }
Karl Schimpf742d72d2014-09-09 11:40:09 -07002576 case naclbitc::FUNC_CODE_INST_ALLOCA: {
2577 // ALLOCA: [Size, align]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002578 if (!isValidRecordSize(2, "alloca"))
Karl Schimpf742d72d2014-09-09 11:40:09 -07002579 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002580 Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex);
Karl Schimpf07af2ac2015-09-30 15:33:41 -07002581 uint32_t Alignment = Context->extractAlignment(this, "Alloca", Values[1]);
Karl Schimpf4019f082014-12-15 13:45:00 -08002582 Ice::Type PtrTy = Ice::getPointerType();
Karl Schimpf742d72d2014-09-09 11:40:09 -07002583 if (ByteCount->getType() != Ice::IceType_i32) {
2584 std::string Buffer;
2585 raw_string_ostream StrBuf(Buffer);
Karl Schimpf97501832014-09-16 13:35:32 -07002586 StrBuf << "Alloca on non-i32 value. Found: " << *ByteCount;
Karl Schimpf742d72d2014-09-09 11:40:09 -07002587 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002588 appendErrorInstruction(PtrTy);
Karl Schimpf742d72d2014-09-09 11:40:09 -07002589 return;
2590 }
Jim Stichnoth8e928382015-02-02 17:03:08 -08002591 CurrentNode->appendInst(Ice::InstAlloca::create(
David Sehr2f3b8ec2015-11-16 16:51:39 -08002592 Func.get(), getNextInstVar(PtrTy), ByteCount, Alignment));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002593 return;
Karl Schimpf742d72d2014-09-09 11:40:09 -07002594 }
Karl Schimpf41689df2014-09-10 14:36:07 -07002595 case naclbitc::FUNC_CODE_INST_LOAD: {
2596 // LOAD: [address, align, ty]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002597 if (!isValidRecordSize(3, "load"))
Karl Schimpf41689df2014-09-10 14:36:07 -07002598 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002599 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex);
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002600 Ice::Type Ty = Context->getSimpleTypeByID(Values[2]);
Karl Schimpf07af2ac2015-09-30 15:33:41 -07002601 uint32_t Alignment = Context->extractAlignment(this, "Load", Values[1]);
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002602 if (!isValidPointerType(Address, "Load")) {
2603 appendErrorInstruction(Ty);
Karl Schimpf41689df2014-09-10 14:36:07 -07002604 return;
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002605 }
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002606 if (!isValidLoadStoreAlignment(Alignment, Ty, "Load")) {
2607 appendErrorInstruction(Ty);
Karl Schimpf41689df2014-09-10 14:36:07 -07002608 return;
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002609 }
Jim Stichnoth8e928382015-02-02 17:03:08 -08002610 CurrentNode->appendInst(Ice::InstLoad::create(
2611 Func.get(), getNextInstVar(Ty), Address, Alignment));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002612 return;
Karl Schimpf41689df2014-09-10 14:36:07 -07002613 }
2614 case naclbitc::FUNC_CODE_INST_STORE: {
2615 // STORE: [address, value, align]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002616 if (!isValidRecordSize(3, "store"))
Karl Schimpf41689df2014-09-10 14:36:07 -07002617 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002618 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex);
Karl Schimpf47661562014-09-11 14:42:49 -07002619 Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex);
Karl Schimpf07af2ac2015-09-30 15:33:41 -07002620 uint32_t Alignment = Context->extractAlignment(this, "Store", Values[2]);
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002621 if (!isValidPointerType(Address, "Store"))
2622 return;
Karl Schimpf41689df2014-09-10 14:36:07 -07002623 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store"))
2624 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002625 CurrentNode->appendInst(
Jim Stichnoth8e928382015-02-02 17:03:08 -08002626 Ice::InstStore::create(Func.get(), Value, Address, Alignment));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002627 return;
Karl Schimpf41689df2014-09-10 14:36:07 -07002628 }
Karl Schimpf8df26f32014-09-19 09:33:26 -07002629 case naclbitc::FUNC_CODE_INST_CALL:
2630 case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: {
2631 // CALL: [cc, fnid, arg0, arg1...]
2632 // CALL_INDIRECT: [cc, fn, returnty, args...]
2633 //
Andrew Scull57e12682015-09-16 11:30:19 -07002634 // Note: The difference between CALL and CALL_INDIRECT is that CALL has a
2635 // reference to an explicit function declaration, while the CALL_INDIRECT
2636 // is just an address. For CALL, we can infer the return type by looking up
2637 // the type signature associated with the function declaration. For
2638 // CALL_INDIRECT we can only infer the type signature via argument types,
2639 // and the corresponding return type stored in CALL_INDIRECT record.
Karl Schimpf8df26f32014-09-19 09:33:26 -07002640 Ice::SizeT ParamsStartIndex = 2;
2641 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) {
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002642 if (!isValidRecordSizeAtLeast(2, "call"))
Karl Schimpf8df26f32014-09-19 09:33:26 -07002643 return;
2644 } else {
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002645 if (!isValidRecordSizeAtLeast(3, "call indirect"))
Karl Schimpf8df26f32014-09-19 09:33:26 -07002646 return;
2647 ParamsStartIndex = 3;
2648 }
2649
Karl Schimpf8df26f32014-09-19 09:33:26 -07002650 uint32_t CalleeIndex = convertRelativeToAbsIndex(Values[1], BaseIndex);
2651 Ice::Operand *Callee = getOperand(CalleeIndex);
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002652
2653 // Pull out signature/return type of call (if possible).
2654 Ice::FunctionDeclaration *Fcn = nullptr;
Karl Schimpfff94f592015-09-18 10:37:44 -07002655 const Ice::FuncSigType *Signature = nullptr;
Karl Schimpf8df26f32014-09-19 09:33:26 -07002656 Ice::Type ReturnType = Ice::IceType_void;
Karl Schimpfe3f64d02014-10-07 10:38:22 -07002657 const Ice::Intrinsics::FullIntrinsicInfo *IntrinsicInfo = nullptr;
Karl Schimpf8df26f32014-09-19 09:33:26 -07002658 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) {
Karl Schimpf958ff342015-09-22 14:09:06 -07002659 Fcn = Context->getFunctionByID(CalleeIndex);
Karl Schimpfff94f592015-09-18 10:37:44 -07002660 Signature = &Fcn->getSignature();
2661 ReturnType = Signature->getReturnType();
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002662 Ice::SizeT NumParams = Values.size() - ParamsStartIndex;
2663 if (NumParams != Signature->getNumArgs()) {
2664 std::string Buffer;
2665 raw_string_ostream StrBuf(Buffer);
2666 StrBuf << "Call to " << printName(Fcn) << " has " << NumParams
2667 << " parameters. Signature expects: " << Signature->getNumArgs();
2668 Error(StrBuf.str());
2669 if (ReturnType != Ice::IceType_void)
2670 setNextLocalInstIndex(nullptr);
2671 return;
2672 }
Karl Schimpf8df26f32014-09-19 09:33:26 -07002673
2674 // Check if this direct call is to an Intrinsic (starts with "llvm.")
Karl Schimpfbba77682016-01-15 07:33:15 -08002675 IntrinsicInfo = Fcn->getIntrinsicInfo(getTranslator().getContext());
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002676 if (IntrinsicInfo && IntrinsicInfo->getNumArgs() != NumParams) {
2677 std::string Buffer;
2678 raw_string_ostream StrBuf(Buffer);
2679 StrBuf << "Call to " << printName(Fcn) << " has " << NumParams
2680 << " parameters. Intrinsic expects: " << Signature->getNumArgs();
Jim Stichnotha67fc442015-03-03 16:13:11 -08002681 Error(StrBuf.str());
Karl Schimpfff94f592015-09-18 10:37:44 -07002682 if (ReturnType != Ice::IceType_void)
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002683 setNextLocalInstIndex(nullptr);
Jim Stichnotha67fc442015-03-03 16:13:11 -08002684 return;
Karl Schimpf8df26f32014-09-19 09:33:26 -07002685 }
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002686 } else { // Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL_INDIRECT
2687 // There is no signature. Assume defined by parameter types.
Karl Schimpf645aa1a2014-10-08 09:05:53 -07002688 ReturnType = Context->getSimpleTypeByID(Values[2]);
Jim Stichnoth0d4fc922015-12-13 21:36:33 -08002689 if (Callee != nullptr)
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002690 isValidPointerType(Callee, "Call indirect");
2691 }
2692
Jim Stichnoth0d4fc922015-12-13 21:36:33 -08002693 if (Callee == nullptr)
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002694 return;
2695
2696 // Extract out the the call parameters.
Jim Stichnoth48e3ae52015-10-01 13:33:35 -07002697 SmallVector<Ice::Operand *, 8> Params;
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002698 for (Ice::SizeT Index = ParamsStartIndex; Index < Values.size(); ++Index) {
2699 Ice::Operand *Op = getRelativeOperand(Values[Index], BaseIndex);
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002700 if (Op == nullptr) {
2701 std::string Buffer;
2702 raw_string_ostream StrBuf(Buffer);
Jim Stichnoth48e3ae52015-10-01 13:33:35 -07002703 StrBuf << "Parameter " << (Index - ParamsStartIndex + 1) << " of "
2704 << printName(Fcn) << " is not defined";
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002705 Error(StrBuf.str());
2706 if (ReturnType != Ice::IceType_void)
2707 setNextLocalInstIndex(nullptr);
2708 return;
2709 }
2710 Params.push_back(Op);
Karl Schimpf8df26f32014-09-19 09:33:26 -07002711 }
2712
Karl Schimpfff94f592015-09-18 10:37:44 -07002713 // Check return type.
2714 if (IntrinsicInfo == nullptr && !isCallReturnType(ReturnType)) {
2715 std::string Buffer;
2716 raw_string_ostream StrBuf(Buffer);
Jim Stichnoth48e3ae52015-10-01 13:33:35 -07002717 StrBuf << "Return type of " << printName(Fcn)
2718 << " is invalid: " << ReturnType;
Karl Schimpfff94f592015-09-18 10:37:44 -07002719 Error(StrBuf.str());
2720 ReturnType = Ice::IceType_i32;
2721 }
2722
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002723 // Type check call parameters.
2724 for (Ice::SizeT Index = 0; Index < Params.size(); ++Index) {
2725 Ice::Operand *Op = Params[Index];
2726 Ice::Type OpType = Op->getType();
2727 if (Signature)
Jim Stichnoth48e3ae52015-10-01 13:33:35 -07002728 verifyCallArgTypeMatches(Fcn, Index, OpType,
2729 Signature->getArgType(Index));
Karl Schimpfbba77682016-01-15 07:33:15 -08002730 else if (!isCallParameterType(OpType)) {
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002731 std::string Buffer;
2732 raw_string_ostream StrBuf(Buffer);
2733 StrBuf << "Argument " << *Op << " of " << printName(Fcn)
2734 << " has invalid type: " << Op->getType();
2735 Error(StrBuf.str());
2736 appendErrorInstruction(ReturnType);
Karl Schimpfbba77682016-01-15 07:33:15 -08002737 return;
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002738 }
2739 }
2740
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002741 // Extract call information.
2742 uint64_t CCInfo = Values[0];
2743 CallingConv::ID CallingConv;
2744 if (!naclbitc::DecodeCallingConv(CCInfo >> 1, CallingConv)) {
2745 std::string Buffer;
2746 raw_string_ostream StrBuf(Buffer);
2747 StrBuf << "Function call calling convention value " << (CCInfo >> 1)
2748 << " not understood.";
2749 Error(StrBuf.str());
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002750 appendErrorInstruction(ReturnType);
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002751 return;
2752 }
Jim Stichnoth2d6c8262016-02-07 09:50:27 -08002753 const bool IsTailCall = (CCInfo & 1);
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002754
Karl Schimpf8df26f32014-09-19 09:33:26 -07002755 // Create the call instruction.
Karl Schimpfe3f64d02014-10-07 10:38:22 -07002756 Ice::Variable *Dest = (ReturnType == Ice::IceType_void)
2757 ? nullptr
2758 : getNextInstVar(ReturnType);
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08002759 std::unique_ptr<Ice::InstCall> Instr;
Karl Schimpf8df26f32014-09-19 09:33:26 -07002760 if (IntrinsicInfo) {
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08002761 Instr.reset(Ice::InstIntrinsicCall::create(
2762 Func.get(), Params.size(), Dest, Callee, IntrinsicInfo->Info));
Karl Schimpf8df26f32014-09-19 09:33:26 -07002763 } else {
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08002764 Instr.reset(Ice::InstCall::create(Func.get(), Params.size(), Dest, Callee,
2765 IsTailCall));
Karl Schimpf8df26f32014-09-19 09:33:26 -07002766 }
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002767 for (Ice::Operand *Param : Params)
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08002768 Instr->addArg(Param);
2769 CurrentNode->appendInst(Instr.release());
Karl Schimpf8df26f32014-09-19 09:33:26 -07002770 return;
2771 }
Karl Schimpf8f07aa82014-09-17 09:07:20 -07002772 case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF: {
2773 // FORWARDTYPEREF: [opval, ty]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002774 if (!isValidRecordSize(2, "forward type ref"))
Karl Schimpf8f07aa82014-09-17 09:07:20 -07002775 return;
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002776 Ice::Type OpType = Context->getSimpleTypeByID(Values[1]);
Jim Stichnoth0d4fc922015-12-13 21:36:33 -08002777 setOperand(Values[0], createInstVar(OpType));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002778 return;
Karl Schimpf8f07aa82014-09-17 09:07:20 -07002779 }
Karl Schimpfd6064a12014-08-27 15:34:58 -07002780 default:
2781 // Generate error message!
2782 BlockParserBaseClass::ProcessRecord();
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002783 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -07002784 }
Karl Schimpfd6064a12014-08-27 15:34:58 -07002785}
2786
Karl Schimpff12355e2014-09-08 13:41:09 -07002787/// Parses constants within a function block.
Karl Schimpfe8457a22016-03-31 10:20:23 -07002788class ConstantsParser final : public BlockParserBaseClass {
Jim Stichnothc6ead202015-02-24 09:30:30 -08002789 ConstantsParser() = delete;
Jim Stichnoth0795ba02014-10-01 14:23:01 -07002790 ConstantsParser(const ConstantsParser &) = delete;
2791 ConstantsParser &operator=(const ConstantsParser &) = delete;
Karl Schimpff12355e2014-09-08 13:41:09 -07002792
2793public:
2794 ConstantsParser(unsigned BlockID, FunctionParser *FuncParser)
Karl Schimpf58455872014-11-03 11:29:39 -08002795 : BlockParserBaseClass(BlockID, FuncParser),
2796 Timer(Ice::TimerStack::TT_parseConstants, getTranslator().getContext()),
Jim Stichnotheafb56c2015-06-22 10:35:22 -07002797 FuncParser(FuncParser) {}
Karl Schimpff12355e2014-09-08 13:41:09 -07002798
Jim Stichnothe587d942015-06-22 15:49:04 -07002799 ~ConstantsParser() override = default;
Karl Schimpff12355e2014-09-08 13:41:09 -07002800
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002801 const char *getBlockName() const override { return "constants"; }
2802
Karl Schimpff12355e2014-09-08 13:41:09 -07002803private:
Karl Schimpf58455872014-11-03 11:29:39 -08002804 Ice::TimerMarker Timer;
Karl Schimpff12355e2014-09-08 13:41:09 -07002805 // The parser of the function block this constants block appears in.
2806 FunctionParser *FuncParser;
2807 // The type to use for succeeding constants.
Jim Stichnotheafb56c2015-06-22 10:35:22 -07002808 Ice::Type NextConstantType = Ice::IceType_void;
Karl Schimpff12355e2014-09-08 13:41:09 -07002809
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07002810 void ProcessRecord() override;
Karl Schimpff12355e2014-09-08 13:41:09 -07002811
2812 Ice::GlobalContext *getContext() { return getTranslator().getContext(); }
2813
Andrew Scull57e12682015-09-16 11:30:19 -07002814 // Returns true if the type to use for succeeding constants is defined. If
2815 // false, also generates an error message.
Karl Schimpff12355e2014-09-08 13:41:09 -07002816 bool isValidNextConstantType() {
2817 if (NextConstantType != Ice::IceType_void)
2818 return true;
2819 Error("Constant record not preceded by set type record");
2820 return false;
2821 }
2822};
2823
2824void ConstantsParser::ProcessRecord() {
2825 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
2826 switch (Record.GetCode()) {
2827 case naclbitc::CST_CODE_SETTYPE: {
2828 // SETTYPE: [typeid]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002829 if (!isValidRecordSize(1, "set type"))
Karl Schimpff12355e2014-09-08 13:41:09 -07002830 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -07002831 NextConstantType = Context->getSimpleTypeByID(Values[0]);
Karl Schimpff12355e2014-09-08 13:41:09 -07002832 if (NextConstantType == Ice::IceType_void)
2833 Error("constants block set type not allowed for void type");
2834 return;
2835 }
2836 case naclbitc::CST_CODE_UNDEF: {
2837 // UNDEF
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002838 if (!isValidRecordSize(0, "undef"))
Karl Schimpff12355e2014-09-08 13:41:09 -07002839 return;
2840 if (!isValidNextConstantType())
2841 return;
2842 FuncParser->setNextConstantID(
2843 getContext()->getConstantUndef(NextConstantType));
2844 return;
2845 }
2846 case naclbitc::CST_CODE_INTEGER: {
2847 // INTEGER: [intval]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002848 if (!isValidRecordSize(1, "integer"))
Karl Schimpff12355e2014-09-08 13:41:09 -07002849 return;
2850 if (!isValidNextConstantType())
2851 return;
Karl Schimpf4019f082014-12-15 13:45:00 -08002852 if (Ice::isScalarIntegerType(NextConstantType)) {
Karl Schimpfa5295b02015-12-01 11:24:53 -08002853 BitcodeInt Value(Ice::getScalarIntBitWidth(NextConstantType),
Karl Schimpf32817482014-12-15 09:52:26 -08002854 NaClDecodeSignRotatedValue(Values[0]));
Jim Stichnothd2cb4362014-11-20 11:24:42 -08002855 if (Ice::Constant *C = getContext()->getConstantInt(
2856 NextConstantType, Value.getSExtValue())) {
2857 FuncParser->setNextConstantID(C);
2858 return;
2859 }
Karl Schimpff12355e2014-09-08 13:41:09 -07002860 }
2861 std::string Buffer;
2862 raw_string_ostream StrBuf(Buffer);
2863 StrBuf << "constant block integer record for non-integer type "
2864 << NextConstantType;
2865 Error(StrBuf.str());
2866 return;
2867 }
2868 case naclbitc::CST_CODE_FLOAT: {
2869 // FLOAT: [fpval]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002870 if (!isValidRecordSize(1, "float"))
Karl Schimpff12355e2014-09-08 13:41:09 -07002871 return;
2872 if (!isValidNextConstantType())
2873 return;
2874 switch (NextConstantType) {
2875 case Ice::IceType_f32: {
Karl Schimpfa5295b02015-12-01 11:24:53 -08002876 const BitcodeInt Value(32, static_cast<uint32_t>(Values[0]));
2877 float FpValue = Value.convertToFp<int32_t, float>();
Karl Schimpf32817482014-12-15 09:52:26 -08002878 FuncParser->setNextConstantID(getContext()->getConstantFloat(FpValue));
Karl Schimpff12355e2014-09-08 13:41:09 -07002879 return;
2880 }
2881 case Ice::IceType_f64: {
Karl Schimpfa5295b02015-12-01 11:24:53 -08002882 const BitcodeInt Value(64, Values[0]);
2883 double FpValue = Value.convertToFp<uint64_t, double>();
Karl Schimpf32817482014-12-15 09:52:26 -08002884 FuncParser->setNextConstantID(getContext()->getConstantDouble(FpValue));
Karl Schimpff12355e2014-09-08 13:41:09 -07002885 return;
2886 }
2887 default: {
2888 std::string Buffer;
2889 raw_string_ostream StrBuf(Buffer);
2890 StrBuf << "constant block float record for non-floating type "
2891 << NextConstantType;
2892 Error(StrBuf.str());
2893 return;
2894 }
2895 }
2896 }
2897 default:
2898 // Generate error message!
2899 BlockParserBaseClass::ProcessRecord();
2900 return;
2901 }
2902}
2903
Karl Schimpfc132b762014-09-11 09:43:47 -07002904// Parses valuesymtab blocks appearing in a function block.
Karl Schimpfe8457a22016-03-31 10:20:23 -07002905class FunctionValuesymtabParser final : public ValuesymtabParser {
Jim Stichnothc6ead202015-02-24 09:30:30 -08002906 FunctionValuesymtabParser() = delete;
Jim Stichnoth0795ba02014-10-01 14:23:01 -07002907 FunctionValuesymtabParser(const FunctionValuesymtabParser &) = delete;
2908 void operator=(const FunctionValuesymtabParser &) = delete;
Karl Schimpfc132b762014-09-11 09:43:47 -07002909
2910public:
2911 FunctionValuesymtabParser(unsigned BlockID, FunctionParser *EnclosingParser)
Karl Schimpf58455872014-11-03 11:29:39 -08002912 : ValuesymtabParser(BlockID, EnclosingParser),
2913 Timer(Ice::TimerStack::TT_parseFunctionValuesymtabs,
2914 getTranslator().getContext()) {}
Karl Schimpfc132b762014-09-11 09:43:47 -07002915
2916private:
Karl Schimpf58455872014-11-03 11:29:39 -08002917 Ice::TimerMarker Timer;
Karl Schimpfc132b762014-09-11 09:43:47 -07002918 // Returns the enclosing function parser.
2919 FunctionParser *getFunctionParser() const {
2920 return reinterpret_cast<FunctionParser *>(GetEnclosingParser());
2921 }
2922
Karl Schimpfe8457a22016-03-31 10:20:23 -07002923 const char *getTableKind() const override { return "Function"; }
Karl Schimpf52863b12015-09-16 13:51:21 -07002924
Karl Schimpfe8457a22016-03-31 10:20:23 -07002925 void setValueName(NaClBcIndexSize_t Index, StringType &Name) override;
2926 void setBbName(NaClBcIndexSize_t Index, StringType &Name) override;
Karl Schimpfc132b762014-09-11 09:43:47 -07002927
Andrew Scull57e12682015-09-16 11:30:19 -07002928 // Reports that the assignment of Name to the value associated with index is
2929 // not possible, for the given Context.
Karl Schimpf74cd8832015-06-23 11:05:01 -07002930 void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index,
Karl Schimpfc132b762014-09-11 09:43:47 -07002931 StringType &Name) {
2932 std::string Buffer;
2933 raw_string_ostream StrBuf(Buffer);
2934 StrBuf << "Function-local " << Context << " name '" << Name
2935 << "' can't be associated with index " << Index;
2936 Error(StrBuf.str());
2937 }
2938};
2939
Karl Schimpf74cd8832015-06-23 11:05:01 -07002940void FunctionValuesymtabParser::setValueName(NaClBcIndexSize_t Index,
2941 StringType &Name) {
Karl Schimpfc132b762014-09-11 09:43:47 -07002942 // Note: We check when Index is too small, so that we can error recover
2943 // (FP->getOperand will create fatal error).
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002944 if (Index < getFunctionParser()->getNumGlobalIDs()) {
Karl Schimpf52863b12015-09-16 13:51:21 -07002945 reportUnableToAssign("Global value", Index, Name);
Karl Schimpfc132b762014-09-11 09:43:47 -07002946 return;
2947 }
2948 Ice::Operand *Op = getFunctionParser()->getOperand(Index);
Jim Stichnoth54f3d512015-12-11 09:53:00 -08002949 if (auto *V = dyn_cast<Ice::Variable>(Op)) {
Jim Stichnoth20b71f52015-06-24 15:52:24 -07002950 if (Ice::BuildDefs::dump()) {
Jim Stichnoth9a04c072014-12-11 15:51:42 -08002951 std::string Nm(Name.data(), Name.size());
2952 V->setName(getFunctionParser()->getFunc(), Nm);
2953 }
Karl Schimpfc132b762014-09-11 09:43:47 -07002954 } else {
Karl Schimpf52863b12015-09-16 13:51:21 -07002955 reportUnableToAssign("Local value", Index, Name);
Karl Schimpfc132b762014-09-11 09:43:47 -07002956 }
2957}
2958
Karl Schimpf74cd8832015-06-23 11:05:01 -07002959void FunctionValuesymtabParser::setBbName(NaClBcIndexSize_t Index,
2960 StringType &Name) {
Karl Schimpfac7d7342015-08-06 12:55:23 -07002961 if (!Ice::BuildDefs::dump())
2962 return;
Karl Schimpf98ed4462015-08-14 13:08:42 -07002963 if (Index >= getFunctionParser()->getFunc()->getNumNodes()) {
Karl Schimpf52863b12015-09-16 13:51:21 -07002964 reportUnableToAssign("Basic block", Index, Name);
Karl Schimpf98ed4462015-08-14 13:08:42 -07002965 return;
2966 }
Karl Schimpfc132b762014-09-11 09:43:47 -07002967 std::string Nm(Name.data(), Name.size());
Karl Schimpf98ed4462015-08-14 13:08:42 -07002968 if (Ice::BuildDefs::dump())
2969 getFunctionParser()->getFunc()->getNodes()[Index]->setName(Nm);
Karl Schimpfc132b762014-09-11 09:43:47 -07002970}
2971
Karl Schimpff12355e2014-09-08 13:41:09 -07002972bool FunctionParser::ParseBlock(unsigned BlockID) {
Jim Stichnothf5fdd232016-05-09 12:24:36 -07002973#ifndef PNACL_LLVM
2974 constexpr bool PNaClAllowLocalSymbolTables = true;
2975#endif // !PNACL_LLVM
Karl Schimpff12355e2014-09-08 13:41:09 -07002976 switch (BlockID) {
2977 case naclbitc::CONSTANTS_BLOCK_ID: {
2978 ConstantsParser Parser(BlockID, this);
2979 return Parser.ParseThisBlock();
2980 }
Karl Schimpfc132b762014-09-11 09:43:47 -07002981 case naclbitc::VALUE_SYMTAB_BLOCK_ID: {
2982 if (PNaClAllowLocalSymbolTables) {
2983 FunctionValuesymtabParser Parser(BlockID, this);
2984 return Parser.ParseThisBlock();
2985 }
2986 break;
Karl Schimpff12355e2014-09-08 13:41:09 -07002987 }
Karl Schimpfc132b762014-09-11 09:43:47 -07002988 default:
2989 break;
2990 }
2991 return BlockParserBaseClass::ParseBlock(BlockID);
Karl Schimpff12355e2014-09-08 13:41:09 -07002992}
2993
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002994/// Parses the module block in the bitcode file.
Karl Schimpfe8457a22016-03-31 10:20:23 -07002995class ModuleParser final : public BlockParserBaseClass {
Jim Stichnothc6ead202015-02-24 09:30:30 -08002996 ModuleParser() = delete;
2997 ModuleParser(const ModuleParser &) = delete;
2998 ModuleParser &operator=(const ModuleParser &) = delete;
2999
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003000public:
3001 ModuleParser(unsigned BlockID, TopLevelParser *Context)
Karl Schimpf6ff33d22014-09-22 10:28:42 -07003002 : BlockParserBaseClass(BlockID, Context),
Karl Schimpf58455872014-11-03 11:29:39 -08003003 Timer(Ice::TimerStack::TT_parseModule,
Karl Schimpf3dd127e2016-03-31 13:22:11 -07003004 Context->getTranslator().getContext()),
Karl Schimpfd4699942016-04-02 09:55:31 -07003005 IsParseParallel(Ice::getFlags().isParseParallel()) {}
Jim Stichnothe587d942015-06-22 15:49:04 -07003006 ~ModuleParser() override = default;
Karl Schimpf2f6f8602014-12-01 13:39:00 -08003007 const char *getBlockName() const override { return "module"; }
Karl Schimpfe8457a22016-03-31 10:20:23 -07003008 NaClBitstreamCursor &getCursor() const { return Record.GetCursor(); }
Karl Schimpf2f6f8602014-12-01 13:39:00 -08003009
Karl Schimpf5ee234a2014-09-12 10:41:40 -07003010private:
Karl Schimpf58455872014-11-03 11:29:39 -08003011 Ice::TimerMarker Timer;
Karl Schimpf9d98d792014-10-13 15:01:08 -07003012 // True if we have already installed names for unnamed global declarations,
3013 // and have generated global constant initializers.
Jim Stichnotheafb56c2015-06-22 10:35:22 -07003014 bool GlobalDeclarationNamesAndInitializersInstalled = false;
Karl Schimpfc49eeae2015-09-17 10:19:48 -07003015 // True if we have already processed the symbol table for the module.
3016 bool FoundValuesymtab = false;
Karl Schimpf3dd127e2016-03-31 13:22:11 -07003017 const bool IsParseParallel;
Karl Schimpf6ff33d22014-09-22 10:28:42 -07003018
Andrew Scull57e12682015-09-16 11:30:19 -07003019 // Generates names for unnamed global addresses (i.e. functions and global
3020 // variables). Then lowers global variable declaration initializers to the
3021 // target. May be called multiple times. Only the first call will do the
3022 // installation.
Karl Schimpf74cd8832015-06-23 11:05:01 -07003023 void installGlobalNamesAndGlobalVarInitializers() {
Karl Schimpf9d98d792014-10-13 15:01:08 -07003024 if (!GlobalDeclarationNamesAndInitializersInstalled) {
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -08003025 Context->installGlobalNames();
3026 Context->createValueIDs();
Karl Schimpfbba77682016-01-15 07:33:15 -08003027 Context->verifyFunctionTypeSignatures();
Karl Schimpfc49eeae2015-09-17 10:19:48 -07003028 std::unique_ptr<Ice::VariableDeclarationList> Globals =
3029 Context->getGlobalVariables();
3030 if (Globals)
3031 getTranslator().lowerGlobals(std::move(Globals));
Karl Schimpf9d98d792014-10-13 15:01:08 -07003032 GlobalDeclarationNamesAndInitializersInstalled = true;
3033 }
3034 }
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07003035 bool ParseBlock(unsigned BlockID) override;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003036
Karl Schimpfe8457a22016-03-31 10:20:23 -07003037 void ExitBlock() override {
3038 installGlobalNamesAndGlobalVarInitializers();
3039 Context->getTranslator().getContext()->waitForWorkerThreads();
3040 }
Karl Schimpf6ff33d22014-09-22 10:28:42 -07003041
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07003042 void ProcessRecord() override;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003043};
3044
Karl Schimpfc132b762014-09-11 09:43:47 -07003045class ModuleValuesymtabParser : public ValuesymtabParser {
Jim Stichnothc6ead202015-02-24 09:30:30 -08003046 ModuleValuesymtabParser() = delete;
Jim Stichnoth0795ba02014-10-01 14:23:01 -07003047 ModuleValuesymtabParser(const ModuleValuesymtabParser &) = delete;
3048 void operator=(const ModuleValuesymtabParser &) = delete;
Karl Schimpfc132b762014-09-11 09:43:47 -07003049
3050public:
3051 ModuleValuesymtabParser(unsigned BlockID, ModuleParser *MP)
Karl Schimpf58455872014-11-03 11:29:39 -08003052 : ValuesymtabParser(BlockID, MP),
3053 Timer(Ice::TimerStack::TT_parseModuleValuesymtabs,
3054 getTranslator().getContext()) {}
Karl Schimpfc132b762014-09-11 09:43:47 -07003055
Jim Stichnothe587d942015-06-22 15:49:04 -07003056 ~ModuleValuesymtabParser() override = default;
Karl Schimpfc132b762014-09-11 09:43:47 -07003057
3058private:
Karl Schimpf58455872014-11-03 11:29:39 -08003059 Ice::TimerMarker Timer;
Karl Schimpfe8457a22016-03-31 10:20:23 -07003060 const char *getTableKind() const override { return "Module"; }
3061 void setValueName(NaClBcIndexSize_t Index, StringType &Name) override;
3062 void setBbName(NaClBcIndexSize_t Index, StringType &Name) override;
Karl Schimpfc132b762014-09-11 09:43:47 -07003063};
3064
Karl Schimpf74cd8832015-06-23 11:05:01 -07003065void ModuleValuesymtabParser::setValueName(NaClBcIndexSize_t Index,
3066 StringType &Name) {
Sean Klein0a3c5232016-03-11 09:49:36 -08003067 Ice::GlobalDeclaration *Decl = Context->getGlobalDeclarationByID(Index);
3068 if (llvm::isa<Ice::VariableDeclaration>(Decl) &&
3069 Decl->isPNaClABIExternalName(Name.str())) {
3070 // Force linkage of (specific) Global Variables be external for the PNaCl
3071 // ABI. PNaCl bitcode has a linkage field for Functions, but not for
3072 // GlobalVariables (because the latter is not needed for pexes, so it has
3073 // been removed).
3074 Decl->setLinkage(llvm::GlobalValue::ExternalLinkage);
3075 }
3076
Jim Stichnoth467ffe52016-03-29 15:01:06 -07003077 // Unconditionally capture the name if it is provided in the input file,
3078 // regardless of whether dump is enabled or whether the symbol is internal vs
3079 // external. This fits in well with the lit tests, and most symbols in a
3080 // conforming pexe are nameless and don't take this path.
3081 Decl->setName(getTranslator().getContext(),
3082 StringRef(Name.data(), Name.size()));
Karl Schimpfc132b762014-09-11 09:43:47 -07003083}
3084
Karl Schimpf74cd8832015-06-23 11:05:01 -07003085void ModuleValuesymtabParser::setBbName(NaClBcIndexSize_t Index,
3086 StringType &Name) {
Karl Schimpf52863b12015-09-16 13:51:21 -07003087 reportUnableToAssign("Basic block", Index, Name);
Karl Schimpfc132b762014-09-11 09:43:47 -07003088}
3089
Karl Schimpfe8457a22016-03-31 10:20:23 -07003090class CfgParserWorkItem final : public Ice::OptWorkItem {
3091 CfgParserWorkItem() = delete;
3092 CfgParserWorkItem(const CfgParserWorkItem &) = delete;
3093 CfgParserWorkItem &operator=(const CfgParserWorkItem &) = delete;
3094
3095public:
3096 CfgParserWorkItem(unsigned BlockID, NaClBcIndexSize_t FcnId,
3097 ModuleParser *ModParser, std::unique_ptr<uint8_t[]> Buffer,
3098 uintptr_t BufferSize, uint64_t StartBit, uint32_t SeqNumber)
3099 : BlockID(BlockID), FcnId(FcnId), ModParser(ModParser),
3100 Buffer(std::move(Buffer)), BufferSize(BufferSize), StartBit(StartBit),
3101 SeqNumber(SeqNumber) {}
3102 std::unique_ptr<Ice::Cfg> getParsedCfg() override;
3103 ~CfgParserWorkItem() override = default;
3104
3105private:
3106 const unsigned BlockID;
3107 const NaClBcIndexSize_t FcnId;
3108 // Note: ModParser can't be const because the function parser needs to
3109 // access non-const member functions (of ModuleParser and TopLevelParser).
3110 // TODO(kschimpf): Fix this issue.
3111 ModuleParser *ModParser;
3112 const std::unique_ptr<uint8_t[]> Buffer;
3113 const uintptr_t BufferSize;
3114 const uint64_t StartBit;
3115 const uint32_t SeqNumber;
3116};
3117
3118std::unique_ptr<Ice::Cfg> CfgParserWorkItem::getParsedCfg() {
3119 NaClBitstreamCursor &OldCursor(ModParser->getCursor());
Karl Schimpf2a9d1862016-04-02 10:06:56 -07003120 llvm::NaClBitstreamReader Reader(OldCursor.getStartWordByteForBit(StartBit),
3121 Buffer.get(), Buffer.get() + BufferSize,
Karl Schimpfe8457a22016-03-31 10:20:23 -07003122 OldCursor.getBitStreamReader());
3123 NaClBitstreamCursor NewCursor(Reader);
3124 NewCursor.JumpToBit(NewCursor.getWordBitNo(StartBit));
3125 FunctionParser Parser(BlockID, ModParser, FcnId, NewCursor);
3126 return Parser.parseFunction(SeqNumber);
3127}
3128
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07003129bool ModuleParser::ParseBlock(unsigned BlockID) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003130 switch (BlockID) {
3131 case naclbitc::BLOCKINFO_BLOCK_ID:
3132 return NaClBitcodeParser::ParseBlock(BlockID);
3133 case naclbitc::TYPE_BLOCK_ID_NEW: {
3134 TypesParser Parser(BlockID, this);
3135 return Parser.ParseThisBlock();
3136 }
3137 case naclbitc::GLOBALVAR_BLOCK_ID: {
3138 GlobalsParser Parser(BlockID, this);
3139 return Parser.ParseThisBlock();
3140 }
3141 case naclbitc::VALUE_SYMTAB_BLOCK_ID: {
Karl Schimpfc49eeae2015-09-17 10:19:48 -07003142 if (FoundValuesymtab)
3143 Fatal("Duplicate valuesymtab in module");
3144
Karl Schimpf28fc2d72015-09-22 13:14:55 -07003145 // If we have already processed a function block (i.e. we have already
3146 // installed global names and variable initializers) we can no longer accept
3147 // the value symbol table. Names have already been generated.
3148 if (GlobalDeclarationNamesAndInitializersInstalled)
3149 Fatal("Module valuesymtab not allowed after function blocks");
3150
Karl Schimpfc49eeae2015-09-17 10:19:48 -07003151 FoundValuesymtab = true;
Karl Schimpfc132b762014-09-11 09:43:47 -07003152 ModuleValuesymtabParser Parser(BlockID, this);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003153 return Parser.ParseThisBlock();
3154 }
3155 case naclbitc::FUNCTION_BLOCK_ID: {
Karl Schimpf74cd8832015-06-23 11:05:01 -07003156 installGlobalNamesAndGlobalVarInitializers();
Karl Schimpfe8457a22016-03-31 10:20:23 -07003157 Ice::GlobalContext *Ctx = Context->getTranslator().getContext();
3158 uint32_t SeqNumber = Context->getTranslator().getNextSequenceNumber();
3159 NaClBcIndexSize_t FcnId = Context->getNextFunctionBlockValueID();
Karl Schimpf3dd127e2016-03-31 13:22:11 -07003160 if (IsParseParallel) {
Karl Schimpfe8457a22016-03-31 10:20:23 -07003161 // Skip the block and copy into a buffer. Note: We copy into a buffer
3162 // using the top-level parser to make sure that the underlying
3163 // buffer reading from the data streamer is not thread safe.
3164 NaClBitstreamCursor &Cursor = Record.GetCursor();
3165 uint64_t StartBit = Cursor.GetCurrentBitNo();
3166 if (SkipBlock())
3167 return true;
3168 const uint64_t EndBit = Cursor.GetCurrentBitNo();
3169 const uintptr_t StartByte = Cursor.getStartWordByteForBit(StartBit);
3170 const uintptr_t EndByte = Cursor.getEndWordByteForBit(EndBit);
3171 const uintptr_t BufferSize = EndByte - StartByte;
3172 std::unique_ptr<uint8_t[]> Buffer((uint8_t *)(new uint8_t[BufferSize]));
3173 for (size_t i = Cursor.fillBuffer(Buffer.get(), BufferSize, StartByte);
3174 i < BufferSize; ++i) {
3175 Buffer[i] = 0;
3176 }
3177 Ctx->optQueueBlockingPush(Ice::makeUnique<CfgParserWorkItem>(
3178 BlockID, FcnId, this, std::move(Buffer), BufferSize, StartBit,
3179 SeqNumber));
3180 return false;
3181 } else {
3182 FunctionParser Parser(BlockID, this, FcnId);
3183 std::unique_ptr<Ice::Cfg> Func = Parser.parseFunction(SeqNumber);
3184 bool Failed = Func->hasError();
3185 getTranslator().translateFcn(std::move(Func));
Karl Schimpfd4699942016-04-02 09:55:31 -07003186 return Failed && !Ice::getFlags().getAllowErrorRecovery();
Karl Schimpfe8457a22016-03-31 10:20:23 -07003187 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003188 }
3189 default:
3190 return BlockParserBaseClass::ParseBlock(BlockID);
3191 }
3192}
3193
3194void ModuleParser::ProcessRecord() {
3195 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
3196 switch (Record.GetCode()) {
3197 case naclbitc::MODULE_CODE_VERSION: {
3198 // VERSION: [version#]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08003199 if (!isValidRecordSize(1, "version"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003200 return;
Karl Schimpf74cd8832015-06-23 11:05:01 -07003201 uint64_t Version = Values[0];
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003202 if (Version != 1) {
3203 std::string Buffer;
3204 raw_string_ostream StrBuf(Buffer);
3205 StrBuf << "Unknown bitstream version: " << Version;
3206 Error(StrBuf.str());
3207 }
3208 return;
3209 }
3210 case naclbitc::MODULE_CODE_FUNCTION: {
3211 // FUNCTION: [type, callingconv, isproto, linkage]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08003212 if (!isValidRecordSize(4, "address"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003213 return;
Karl Schimpf9d98d792014-10-13 15:01:08 -07003214 const Ice::FuncSigType &Signature = Context->getFuncSigTypeByID(Values[0]);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003215 CallingConv::ID CallingConv;
3216 if (!naclbitc::DecodeCallingConv(Values[1], CallingConv)) {
3217 std::string Buffer;
3218 raw_string_ostream StrBuf(Buffer);
Karl Schimpf2f6f8602014-12-01 13:39:00 -08003219 StrBuf << "Function address has unknown calling convention: "
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003220 << Values[1];
3221 Error(StrBuf.str());
3222 return;
3223 }
3224 GlobalValue::LinkageTypes Linkage;
3225 if (!naclbitc::DecodeLinkage(Values[3], Linkage)) {
3226 std::string Buffer;
3227 raw_string_ostream StrBuf(Buffer);
Karl Schimpf2f6f8602014-12-01 13:39:00 -08003228 StrBuf << "Function address has unknown linkage. Found " << Values[3];
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003229 Error(StrBuf.str());
3230 return;
3231 }
Karl Schimpf0c729c82015-01-28 10:58:25 -08003232 bool IsProto = Values[2] == 1;
Jim Stichnoth54f3d512015-12-11 09:53:00 -08003233 auto *Func = Ice::FunctionDeclaration::create(
John Porto1bec8bc2015-06-22 10:51:13 -07003234 Context->getTranslator().getContext(), Signature, CallingConv, Linkage,
3235 IsProto);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003236 Context->setNextFunctionID(Func);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003237 return;
3238 }
3239 default:
3240 BlockParserBaseClass::ProcessRecord();
3241 return;
3242 }
3243}
3244
3245bool TopLevelParser::ParseBlock(unsigned BlockID) {
3246 if (BlockID == naclbitc::MODULE_BLOCK_ID) {
Karl Schimpf0b8763e2015-09-22 10:41:11 -07003247 if (ParsedModuleBlock)
3248 Fatal("Input can't contain more than one module");
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003249 ModuleParser Parser(BlockID, this);
Karl Schimpf0b8763e2015-09-22 10:41:11 -07003250 bool ParseFailed = Parser.ParseThisBlock();
3251 ParsedModuleBlock = true;
3252 return ParseFailed;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003253 }
3254 // Generate error message by using default block implementation.
3255 BlockParserBaseClass Parser(BlockID, this);
3256 return Parser.ParseThisBlock();
3257}
3258
Jim Stichnoth989a7032014-08-08 10:13:44 -07003259} // end of anonymous namespace
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003260
3261namespace Ice {
3262
Karl Schimpf2e7daef2015-01-09 13:04:13 -08003263void PNaClTranslator::translateBuffer(const std::string &IRFilename,
3264 MemoryBuffer *MemBuf) {
Jan Voungc1f07ea2015-03-06 14:53:30 -08003265 std::unique_ptr<MemoryObject> MemObj(getNonStreamedMemoryObject(
3266 reinterpret_cast<const unsigned char *>(MemBuf->getBufferStart()),
3267 reinterpret_cast<const unsigned char *>(MemBuf->getBufferEnd())));
3268 translate(IRFilename, std::move(MemObj));
3269}
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003270
Jan Voungc1f07ea2015-03-06 14:53:30 -08003271void PNaClTranslator::translate(const std::string &IRFilename,
3272 std::unique_ptr<MemoryObject> &&MemObj) {
Andrew Scull57e12682015-09-16 11:30:19 -07003273 // On error, we report_fatal_error to avoid destroying the MemObj. That may
3274 // still be in use by IceBrowserCompileServer. Otherwise, we need to change
3275 // the MemObj to be ref-counted, or have a wrapper, or simply leak. We also
3276 // need a hook to tell the IceBrowserCompileServer to unblock its
3277 // QueueStreamer.
Jan Voung2f7f2b72015-06-03 17:50:20 -07003278 // https://code.google.com/p/nativeclient/issues/detail?id=4163
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003279 // Read header and verify it is good.
3280 NaClBitcodeHeader Header;
Karl Schimpfb33a2af2015-05-12 08:26:23 -07003281 if (Header.Read(MemObj.get())) {
Jan Voung2f7f2b72015-06-03 17:50:20 -07003282 llvm::report_fatal_error("Invalid PNaCl bitcode header");
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003283 }
Karl Schimpfb33a2af2015-05-12 08:26:23 -07003284 if (!Header.IsSupported()) {
Karl Schimpf0b8763e2015-09-22 10:41:11 -07003285 getContext()->getStrError() << Header.Unsupported();
Karl Schimpfb33a2af2015-05-12 08:26:23 -07003286 if (!Header.IsReadable()) {
Jan Voung2f7f2b72015-06-03 17:50:20 -07003287 llvm::report_fatal_error("Invalid PNaCl bitcode header");
Karl Schimpfb33a2af2015-05-12 08:26:23 -07003288 }
3289 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003290
3291 // Create a bitstream reader to read the bitcode file.
Karl Schimpfb33a2af2015-05-12 08:26:23 -07003292 NaClBitstreamReader InputStreamFile(MemObj.release(), Header);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003293 NaClBitstreamCursor InputStream(InputStreamFile);
3294
Karl Schimpf22ed4eb2015-03-04 12:17:20 -08003295 TopLevelParser Parser(*this, InputStream, ErrorStatus);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003296 while (!InputStream.AtEndOfStream()) {
3297 if (Parser.Parse()) {
Jim Stichnothfa4efea2015-01-27 05:06:03 -08003298 ErrorStatus.assign(EC_Bitcode);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003299 return;
3300 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003301 }
3302
Karl Schimpf0b8763e2015-09-22 10:41:11 -07003303 if (!Parser.parsedModuleBlock()) {
3304 std::string Buffer;
3305 raw_string_ostream StrBuf(Buffer);
3306 StrBuf << IRFilename << ": Does not contain a module!";
3307 llvm::report_fatal_error(StrBuf.str());
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003308 }
Jan Voungc1f07ea2015-03-06 14:53:30 -08003309 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) {
Jan Voung2f7f2b72015-06-03 17:50:20 -07003310 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes");
Jan Voungc1f07ea2015-03-06 14:53:30 -08003311 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003312}
3313
Jim Stichnoth989a7032014-08-08 10:13:44 -07003314} // end of namespace Ice