blob: ed19f61ccfd5b869ecceec984fd3c7785b07c25a [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 Stichnoth98da9662015-06-27 06:38:08 -070025
Jim Stichnothb0051df2016-01-13 11:39:15 -080026#ifdef __clang__
Jim Stichnoth98da9662015-06-27 06:38:08 -070027#pragma clang diagnostic push
28#pragma clang diagnostic ignored "-Wunused-parameter"
Jim Stichnothb0051df2016-01-13 11:39:15 -080029#endif // __clang__
30
Karl Schimpf52863b12015-09-16 13:51:21 -070031#include "llvm/ADT/Hashing.h"
John Porto67f8de92015-06-25 10:14:17 -070032#include "llvm/ADT/SmallString.h"
33#include "llvm/Bitcode/NaCl/NaClBitcodeDecoders.h"
34#include "llvm/Bitcode/NaCl/NaClBitcodeDefs.h"
35#include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h"
36#include "llvm/Bitcode/NaCl/NaClBitcodeParser.h"
37#include "llvm/Bitcode/NaCl/NaClReaderWriter.h"
38#include "llvm/Support/Format.h"
39#include "llvm/Support/MemoryBuffer.h"
40#include "llvm/Support/raw_ostream.h"
Jim Stichnothb0051df2016-01-13 11:39:15 -080041
42#ifdef __clang__
Jim Stichnoth98da9662015-06-27 06:38:08 -070043#pragma clang diagnostic pop
Jim Stichnothb0051df2016-01-13 11:39:15 -080044#endif // __clang__
45
46#include <unordered_set>
Karl Schimpf8d7abae2014-07-07 14:50:30 -070047
Karl Schimpf52863b12015-09-16 13:51:21 -070048// Define a hash function for SmallString's, so that it can be used in hash
49// tables.
50namespace std {
51template <unsigned InternalLen> struct hash<llvm::SmallString<InternalLen>> {
52 size_t operator()(const llvm::SmallString<InternalLen> &Key) const {
53 return llvm::hash_combine_range(Key.begin(), Key.end());
54 }
55};
56} // end of namespace std
57
Karl Schimpf8d7abae2014-07-07 14:50:30 -070058namespace {
Karl Schimpf9d98d792014-10-13 15:01:08 -070059using namespace llvm;
Karl Schimpf8d7abae2014-07-07 14:50:30 -070060
Andrew Scull57e12682015-09-16 11:30:19 -070061// Models elements in the list of types defined in the types block. These
62// elements can be undefined, a (simple) type, or a function type signature.
63// Note that an extended type is undefined on construction. Use methods
64// setAsSimpleType and setAsFuncSigType to define the extended type.
Karl Schimpf645aa1a2014-10-08 09:05:53 -070065class ExtendedType {
Karl Schimpf645aa1a2014-10-08 09:05:53 -070066 ExtendedType &operator=(const ExtendedType &Ty) = delete;
Jim Stichnothdd842db2015-01-27 12:53:53 -080067
Karl Schimpf645aa1a2014-10-08 09:05:53 -070068public:
69 /// Discriminator for LLVM-style RTTI.
70 enum TypeKind { Undefined, Simple, FuncSig };
71
Jim Stichnotheafb56c2015-06-22 10:35:22 -070072 ExtendedType() = default;
Jim Stichnoth7e571362015-01-09 11:43:26 -080073 ExtendedType(const ExtendedType &Ty) = default;
Karl Schimpf645aa1a2014-10-08 09:05:53 -070074
Jim Stichnotheafb56c2015-06-22 10:35:22 -070075 virtual ~ExtendedType() = default;
Karl Schimpf645aa1a2014-10-08 09:05:53 -070076
77 ExtendedType::TypeKind getKind() const { return Kind; }
Karl Schimpfaff9fa22014-10-29 14:32:07 -070078 void dump(Ice::Ostream &Stream) const;
Karl Schimpf645aa1a2014-10-08 09:05:53 -070079
Andrew Scull57e12682015-09-16 11:30:19 -070080 /// Changes the extended type to a simple type with the given / value.
Karl Schimpf645aa1a2014-10-08 09:05:53 -070081 void setAsSimpleType(Ice::Type Ty) {
82 assert(Kind == Undefined);
83 Kind = Simple;
84 Signature.setReturnType(Ty);
85 }
86
87 /// Changes the extended type to an (empty) function signature type.
88 void setAsFunctionType() {
89 assert(Kind == Undefined);
90 Kind = FuncSig;
91 }
92
93protected:
Andrew Scull57e12682015-09-16 11:30:19 -070094 // Note: For simple types, the return type of the signature will be used to
95 // hold the simple type.
Karl Schimpf645aa1a2014-10-08 09:05:53 -070096 Ice::FuncSigType Signature;
97
98private:
Jim Stichnotheafb56c2015-06-22 10:35:22 -070099 ExtendedType::TypeKind Kind = Undefined;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700100};
101
102Ice::Ostream &operator<<(Ice::Ostream &Stream, const ExtendedType &Ty) {
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700103 if (!Ice::BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800104 return Stream;
Karl Schimpfaff9fa22014-10-29 14:32:07 -0700105 Ty.dump(Stream);
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700106 return Stream;
107}
108
109Ice::Ostream &operator<<(Ice::Ostream &Stream, ExtendedType::TypeKind Kind) {
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700110 if (!Ice::BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800111 return Stream;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700112 Stream << "ExtendedType::";
113 switch (Kind) {
114 case ExtendedType::Undefined:
115 Stream << "Undefined";
116 break;
117 case ExtendedType::Simple:
118 Stream << "Simple";
119 break;
120 case ExtendedType::FuncSig:
121 Stream << "FuncSig";
122 break;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700123 }
124 return Stream;
125}
126
127// Models an ICE type as an extended type.
128class SimpleExtendedType : public ExtendedType {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800129 SimpleExtendedType() = delete;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700130 SimpleExtendedType(const SimpleExtendedType &) = delete;
131 SimpleExtendedType &operator=(const SimpleExtendedType &) = delete;
Jim Stichnothdd842db2015-01-27 12:53:53 -0800132
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700133public:
134 Ice::Type getType() const { return Signature.getReturnType(); }
135
136 static bool classof(const ExtendedType *Ty) {
137 return Ty->getKind() == Simple;
138 }
139};
140
141// Models a function signature as an extended type.
142class FuncSigExtendedType : public ExtendedType {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800143 FuncSigExtendedType() = delete;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700144 FuncSigExtendedType(const FuncSigExtendedType &) = delete;
145 FuncSigExtendedType &operator=(const FuncSigExtendedType &) = delete;
Jim Stichnothdd842db2015-01-27 12:53:53 -0800146
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700147public:
148 const Ice::FuncSigType &getSignature() const { return Signature; }
149 void setReturnType(Ice::Type ReturnType) {
150 Signature.setReturnType(ReturnType);
151 }
152 void appendArgType(Ice::Type ArgType) { Signature.appendArgType(ArgType); }
153 static bool classof(const ExtendedType *Ty) {
154 return Ty->getKind() == FuncSig;
155 }
156};
157
Karl Schimpfaff9fa22014-10-29 14:32:07 -0700158void ExtendedType::dump(Ice::Ostream &Stream) const {
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700159 if (!Ice::BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800160 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700161 Stream << Kind;
162 switch (Kind) {
163 case Simple: {
164 Stream << " " << Signature.getReturnType();
165 break;
166 }
167 case FuncSig: {
168 Stream << " " << Signature;
169 }
170 default:
171 break;
172 }
173}
174
Karl Schimpfa5295b02015-12-01 11:24:53 -0800175// Models integer literals as a sequence of bits. Used to read integer values
176// from bitcode files. Based on llvm::APInt.
177class BitcodeInt {
178 BitcodeInt() = delete;
179 BitcodeInt(const BitcodeInt &) = delete;
180 BitcodeInt &operator=(const BitcodeInt &) = delete;
181
182public:
183 BitcodeInt(Ice::SizeT Bits, uint64_t Val) : BitWidth(Bits), Val(Val) {
184 assert(Bits && "bitwidth too small");
185 assert(Bits <= BITS_PER_WORD && "bitwidth too big");
186 clearUnusedBits();
187 }
188
189 int64_t getSExtValue() const {
190 return static_cast<int64_t>(Val << (BITS_PER_WORD - BitWidth)) >>
191 (BITS_PER_WORD - BitWidth);
192 }
193
194 template <typename IntType, typename FpType>
195 inline FpType convertToFp() const {
196 static_assert(sizeof(IntType) == sizeof(FpType),
197 "IntType and FpType should be the same width");
198 assert(BitWidth == sizeof(IntType) * CHAR_BIT);
199 auto V = static_cast<IntType>(Val);
Jim Stichnothb0051df2016-01-13 11:39:15 -0800200 return Ice::Utils::bitCopy<FpType>(V);
Karl Schimpfa5295b02015-12-01 11:24:53 -0800201 }
202
203private:
204 /// Bits in the (internal) value.
205 static const Ice::SizeT BITS_PER_WORD = sizeof(uint64_t) * CHAR_BIT;
206
207 uint32_t BitWidth; /// The number of bits in the floating point number.
208 uint64_t Val; /// The (64-bit) equivalent integer value.
209
210 /// Clear unused high order bits.
211 void clearUnusedBits() {
212 // If all bits are used, we want to leave the value alone.
213 if (BitWidth == BITS_PER_WORD)
214 return;
215
216 // Mask out the high bits.
217 Val &= ~static_cast<uint64_t>(0) >> (BITS_PER_WORD - BitWidth);
218 }
219};
220
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800221class BlockParserBaseClass;
222
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700223// Top-level class to read PNaCl bitcode files, and translate to ICE.
224class TopLevelParser : public NaClBitcodeParser {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800225 TopLevelParser() = delete;
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700226 TopLevelParser(const TopLevelParser &) = delete;
227 TopLevelParser &operator=(const TopLevelParser &) = delete;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700228
229public:
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800230 TopLevelParser(Ice::Translator &Translator, NaClBitstreamCursor &Cursor,
231 Ice::ErrorCode &ErrorStatus)
232 : NaClBitcodeParser(Cursor), Translator(Translator),
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700233 ErrorStatus(ErrorStatus),
234 VariableDeclarations(new Ice::VariableDeclarationList()) {}
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700235
Jim Stichnothe587d942015-06-22 15:49:04 -0700236 ~TopLevelParser() override = default;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700237
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800238 Ice::Translator &getTranslator() const { return Translator; }
Karl Schimpfd6064a12014-08-27 15:34:58 -0700239
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800240 void setBlockParser(BlockParserBaseClass *NewBlockParser) {
241 BlockParser = NewBlockParser;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700242 }
243
Andrew Scull57e12682015-09-16 11:30:19 -0700244 /// Generates error with given Message, occurring at BitPosition within the
245 /// bitcode file. Always returns true.
Karl Schimpf17b1a132015-03-12 09:32:06 -0700246 bool ErrorAt(naclbitc::ErrorLevel Level, uint64_t BitPosition,
247 const std::string &Message) final;
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800248
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800249 /// Generates error message with respect to the current block parser.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700250 bool blockError(const std::string &Message);
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800251
Andrew Scull57e12682015-09-16 11:30:19 -0700252 /// Returns the number of errors found while parsing the bitcode file.
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700253 unsigned getNumErrors() const { return NumErrors; }
254
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700255 /// Changes the size of the type list to the given size.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700256 void resizeTypeIDValues(size_t NewSize) { TypeIDValues.resize(NewSize); }
257
258 size_t getNumTypeIDValues() const { return TypeIDValues.size(); }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700259
Andrew Scull57e12682015-09-16 11:30:19 -0700260 /// Returns the undefined type associated with type ID. Note: Returns extended
261 /// type ready to be defined.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700262 ExtendedType *getTypeByIDForDefining(NaClBcIndexSize_t ID) {
Andrew Scull57e12682015-09-16 11:30:19 -0700263 // Get corresponding element, verifying the value is still undefined (and
264 // hence allowed to be defined).
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700265 ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Undefined);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700266 if (Ty)
267 return Ty;
Karl Schimpf74cd8832015-06-23 11:05:01 -0700268 if (ID >= TypeIDValues.size()) {
269 if (ID >= NaClBcIndexSize_t_Max) {
270 std::string Buffer;
271 raw_string_ostream StrBuf(Buffer);
272 StrBuf << "Can't define more than " << NaClBcIndexSize_t_Max
273 << " types\n";
274 blockError(StrBuf.str());
275 // Recover by using existing type slot.
276 return &TypeIDValues[0];
277 }
Jim Stichnothdd842db2015-01-27 12:53:53 -0800278 TypeIDValues.resize(ID + 1);
Karl Schimpf74cd8832015-06-23 11:05:01 -0700279 }
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700280 return &TypeIDValues[ID];
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700281 }
282
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700283 /// Returns the type associated with the given index.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700284 Ice::Type getSimpleTypeByID(NaClBcIndexSize_t ID) {
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700285 const ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Simple);
286 if (Ty == nullptr)
287 // Return error recovery value.
288 return Ice::IceType_void;
289 return cast<SimpleExtendedType>(Ty)->getType();
290 }
291
292 /// Returns the type signature associated with the given index.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700293 const Ice::FuncSigType &getFuncSigTypeByID(NaClBcIndexSize_t ID) {
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700294 const ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::FuncSig);
295 if (Ty == nullptr)
296 // Return error recovery value.
297 return UndefinedFuncSigType;
298 return cast<FuncSigExtendedType>(Ty)->getSignature();
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700299 }
300
301 /// Sets the next function ID to the given LLVM function.
Karl Schimpf9d98d792014-10-13 15:01:08 -0700302 void setNextFunctionID(Ice::FunctionDeclaration *Fcn) {
Karl Schimpf209318a2015-08-20 13:24:02 -0700303 FunctionDeclarations.push_back(Fcn);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700304 }
305
Andrew Scull57e12682015-09-16 11:30:19 -0700306 /// Returns the value id that should be associated with the the current
307 /// function block. Increments internal counters during call so that it will
308 /// be in correct position for next function block.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700309 NaClBcIndexSize_t getNextFunctionBlockValueID() {
Karl Schimpf209318a2015-08-20 13:24:02 -0700310 size_t NumDeclaredFunctions = FunctionDeclarations.size();
Karl Schimpf0c729c82015-01-28 10:58:25 -0800311 while (NextDefiningFunctionID < NumDeclaredFunctions &&
Karl Schimpf209318a2015-08-20 13:24:02 -0700312 FunctionDeclarations[NextDefiningFunctionID]->isProto())
Karl Schimpf0c729c82015-01-28 10:58:25 -0800313 ++NextDefiningFunctionID;
314 if (NextDefiningFunctionID >= NumDeclaredFunctions)
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800315 Fatal("More function blocks than defined function addresses");
Karl Schimpf0c729c82015-01-28 10:58:25 -0800316 return NextDefiningFunctionID++;
Karl Schimpfd6064a12014-08-27 15:34:58 -0700317 }
318
Karl Schimpf9d98d792014-10-13 15:01:08 -0700319 /// Returns the function associated with ID.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700320 Ice::FunctionDeclaration *getFunctionByID(NaClBcIndexSize_t ID) {
Karl Schimpf209318a2015-08-20 13:24:02 -0700321 if (ID < FunctionDeclarations.size())
322 return FunctionDeclarations[ID];
Karl Schimpf9d98d792014-10-13 15:01:08 -0700323 return reportGetFunctionByIDError(ID);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700324 }
325
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800326 /// Returns the constant associated with the given global value ID.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700327 Ice::Constant *getGlobalConstantByID(NaClBcIndexSize_t ID) {
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800328 assert(ID < ValueIDConstants.size());
329 return ValueIDConstants[ID];
Karl Schimpf9d98d792014-10-13 15:01:08 -0700330 }
331
Andrew Scull57e12682015-09-16 11:30:19 -0700332 /// Install names for all global values without names. Called after the global
333 /// value symbol table is processed, but before any function blocks are
334 /// processed.
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800335 void installGlobalNames() {
336 assert(VariableDeclarations);
337 installGlobalVarNames();
338 installFunctionNames();
339 }
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700340
Karl Schimpfbba77682016-01-15 07:33:15 -0800341 void verifyFunctionTypeSignatures();
342
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800343 void createValueIDs() {
344 assert(VariableDeclarations);
345 ValueIDConstants.reserve(VariableDeclarations->size() +
Karl Schimpf209318a2015-08-20 13:24:02 -0700346 FunctionDeclarations.size());
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800347 createValueIDsForFunctions();
348 createValueIDsForGlobalVars();
Karl Schimpf8df26f32014-09-19 09:33:26 -0700349 }
350
Karl Schimpf9d98d792014-10-13 15:01:08 -0700351 /// Returns the number of function declarations in the bitcode file.
Karl Schimpf209318a2015-08-20 13:24:02 -0700352 size_t getNumFunctionIDs() const { return FunctionDeclarations.size(); }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700353
Andrew Scull57e12682015-09-16 11:30:19 -0700354 /// Returns the number of global declarations (i.e. IDs) defined in the
355 /// bitcode file.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700356 size_t getNumGlobalIDs() const {
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800357 if (VariableDeclarations) {
Karl Schimpf209318a2015-08-20 13:24:02 -0700358 return FunctionDeclarations.size() + VariableDeclarations->size();
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800359 } else {
360 return ValueIDConstants.size();
361 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700362 }
363
Karl Schimpfaa0ce792015-08-07 09:28:57 -0700364 /// Adds the given global declaration to the end of the list of global
365 /// declarations.
366 void addGlobalDeclaration(Ice::VariableDeclaration *Decl) {
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800367 assert(VariableDeclarations);
Karl Schimpfaa0ce792015-08-07 09:28:57 -0700368 VariableDeclarations->push_back(Decl);
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700369 }
370
Karl Schimpf9d98d792014-10-13 15:01:08 -0700371 /// Returns the global variable declaration with the given index.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700372 Ice::VariableDeclaration *getGlobalVariableByID(NaClBcIndexSize_t Index) {
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800373 assert(VariableDeclarations);
374 if (Index < VariableDeclarations->size())
375 return VariableDeclarations->at(Index);
Karl Schimpf9d98d792014-10-13 15:01:08 -0700376 return reportGetGlobalVariableByIDError(Index);
377 }
378
Andrew Scull57e12682015-09-16 11:30:19 -0700379 /// Returns the global declaration (variable or function) with the given
380 /// Index.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700381 Ice::GlobalDeclaration *getGlobalDeclarationByID(NaClBcIndexSize_t Index) {
Karl Schimpf209318a2015-08-20 13:24:02 -0700382 size_t NumFunctionIds = FunctionDeclarations.size();
Karl Schimpf9d98d792014-10-13 15:01:08 -0700383 if (Index < NumFunctionIds)
384 return getFunctionByID(Index);
385 else
386 return getGlobalVariableByID(Index - NumFunctionIds);
387 }
388
Karl Schimpf0b8763e2015-09-22 10:41:11 -0700389 /// Returns true if a module block has been parsed.
390 bool parsedModuleBlock() const { return ParsedModuleBlock; }
391
Andrew Scull57e12682015-09-16 11:30:19 -0700392 /// Returns the list of parsed global variable declarations. Releases
393 /// ownership of the current list of global variables. Note: only returns
394 /// non-null pointer on first call. All successive calls return a null
395 /// pointer.
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800396 std::unique_ptr<Ice::VariableDeclarationList> getGlobalVariables() {
Andrew Scull57e12682015-09-16 11:30:19 -0700397 // Before returning, check that ValidIDConstants has already been built.
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800398 assert(!VariableDeclarations ||
399 VariableDeclarations->size() <= ValueIDConstants.size());
400 return std::move(VariableDeclarations);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700401 }
402
Karl Schimpf07af2ac2015-09-30 15:33:41 -0700403 // Upper limit of alignment power allowed by LLVM
404 static constexpr uint32_t AlignPowerLimit = 29;
405
406 // Extracts the corresponding Alignment to use, given the AlignPower (i.e.
407 // 2**(AlignPower-1), or 0 if AlignPower == 0). Parser defines the block
408 // context the alignment check appears in, and Prefix defines the context the
409 // alignment appears in.
410 uint32_t extractAlignment(NaClBitcodeParser *Parser, const char *Prefix,
411 uint32_t AlignPower) {
412 if (AlignPower <= AlignPowerLimit + 1)
413 return (1 << AlignPower) >> 1;
414 std::string Buffer;
415 raw_string_ostream StrBuf(Buffer);
416 StrBuf << Prefix << " alignment greater than 2**" << AlignPowerLimit
417 << ". Found: 2**" << (AlignPower - 1);
418 Parser->Error(StrBuf.str());
419 // Error recover with value that is always acceptable.
420 return 1;
421 }
422
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700423private:
Karl Schimpfd6064a12014-08-27 15:34:58 -0700424 // The translator associated with the parser.
425 Ice::Translator &Translator;
Karl Schimpfb164d202014-07-11 10:26:34 -0700426 // The exit status that should be set to true if an error occurs.
Jim Stichnothfa4efea2015-01-27 05:06:03 -0800427 Ice::ErrorCode &ErrorStatus;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700428 // The number of errors reported.
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700429 unsigned NumErrors = 0;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700430 // The types associated with each type ID.
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700431 std::vector<ExtendedType> TypeIDValues;
Karl Schimpf0c729c82015-01-28 10:58:25 -0800432 // The set of functions (prototype and defined).
Karl Schimpf209318a2015-08-20 13:24:02 -0700433 Ice::FunctionDeclarationList FunctionDeclarations;
434 // The ID of the next possible defined function ID in FunctionDeclarations.
435 // FunctionDeclarations is filled first. It's the set of functions (either
436 // defined or isproto). Then function definitions are encountered/parsed and
437 // NextDefiningFunctionID is incremented to track the next actually-defined
438 // function.
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700439 size_t NextDefiningFunctionID = 0;
Karl Schimpf9d98d792014-10-13 15:01:08 -0700440 // The set of global variables.
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800441 std::unique_ptr<Ice::VariableDeclarationList> VariableDeclarations;
Karl Schimpf9d98d792014-10-13 15:01:08 -0700442 // Relocatable constants associated with global declarations.
Karl Schimpf209318a2015-08-20 13:24:02 -0700443 Ice::ConstantList ValueIDConstants;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700444 // Error recovery value to use when getFuncSigTypeByID fails.
445 Ice::FuncSigType UndefinedFuncSigType;
Andrew Scull57e12682015-09-16 11:30:19 -0700446 // The block parser currently being applied. Used for error reporting.
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700447 BlockParserBaseClass *BlockParser = nullptr;
Karl Schimpf0b8763e2015-09-22 10:41:11 -0700448 // Defines if a module block has already been parsed.
449 bool ParsedModuleBlock = false;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700450
Jim Stichnoth8e8042c2014-09-25 17:51:47 -0700451 bool ParseBlock(unsigned BlockID) override;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700452
Andrew Scull57e12682015-09-16 11:30:19 -0700453 // Gets extended type associated with the given index, assuming the extended
454 // type is of the WantedKind. Generates error message if corresponding
455 // extended type of WantedKind can't be found, and returns nullptr.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700456 ExtendedType *getTypeByIDAsKind(NaClBcIndexSize_t ID,
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700457 ExtendedType::TypeKind WantedKind) {
458 ExtendedType *Ty = nullptr;
459 if (ID < TypeIDValues.size()) {
460 Ty = &TypeIDValues[ID];
461 if (Ty->getKind() == WantedKind)
462 return Ty;
463 }
464 // Generate an error message and set ErrorStatus.
465 this->reportBadTypeIDAs(ID, Ty, WantedKind);
466 return nullptr;
467 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700468
Andrew Scull57e12682015-09-16 11:30:19 -0700469 // Gives Decl a name if it doesn't already have one. Prefix and NameIndex are
470 // used to generate the name. NameIndex is automatically incremented if a new
471 // name is created. DeclType is literal text describing the type of name
472 // being created. Also generates warning if created names may conflict with
473 // named declarations.
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800474 void installDeclarationName(Ice::GlobalDeclaration *Decl,
475 const Ice::IceString &Prefix,
Karl Schimpf74cd8832015-06-23 11:05:01 -0700476 const char *DeclType,
477 NaClBcIndexSize_t &NameIndex) {
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800478 if (Decl->hasName()) {
479 Translator.checkIfUnnamedNameSafe(Decl->getName(), DeclType, Prefix);
480 } else {
481 Decl->setName(Translator.createUnnamedName(Prefix, NameIndex));
482 ++NameIndex;
483 }
484 }
485
486 // Installs names for global variables without names.
487 void installGlobalVarNames() {
488 assert(VariableDeclarations);
489 const Ice::IceString &GlobalPrefix =
490 getTranslator().getFlags().getDefaultGlobalPrefix();
491 if (!GlobalPrefix.empty()) {
Karl Schimpf74cd8832015-06-23 11:05:01 -0700492 NaClBcIndexSize_t NameIndex = 0;
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800493 for (Ice::VariableDeclaration *Var : *VariableDeclarations) {
494 installDeclarationName(Var, GlobalPrefix, "global", NameIndex);
495 }
496 }
497 }
498
499 // Installs names for functions without names.
500 void installFunctionNames() {
501 const Ice::IceString &FunctionPrefix =
502 getTranslator().getFlags().getDefaultFunctionPrefix();
503 if (!FunctionPrefix.empty()) {
Karl Schimpf74cd8832015-06-23 11:05:01 -0700504 NaClBcIndexSize_t NameIndex = 0;
Karl Schimpf209318a2015-08-20 13:24:02 -0700505 for (Ice::FunctionDeclaration *Func : FunctionDeclarations) {
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800506 installDeclarationName(Func, FunctionPrefix, "function", NameIndex);
507 }
508 }
509 }
510
511 // Builds a constant symbol named Name, suppressing name mangling if
Andrew Scull57e12682015-09-16 11:30:19 -0700512 // SuppressMangling. IsExternal is true iff the symbol is external.
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800513 Ice::Constant *getConstantSym(const Ice::IceString &Name,
514 bool SuppressMangling, bool IsExternal) const {
515 if (IsExternal) {
516 return getTranslator().getContext()->getConstantExternSym(Name);
517 } else {
518 const Ice::RelocOffsetT Offset = 0;
519 return getTranslator().getContext()->getConstantSym(Offset, Name,
520 SuppressMangling);
521 }
522 }
523
Karl Schimpfa313a122015-10-08 10:40:57 -0700524 void reportLinkageError(const char *Kind,
525 const Ice::GlobalDeclaration &Decl) {
526 std::string Buffer;
527 raw_string_ostream StrBuf(Buffer);
528 StrBuf << Kind << " " << Decl.getName()
529 << " has incorrect linkage: " << Decl.getLinkageName();
530 if (Decl.isExternal())
531 StrBuf << "\n Use flag -allow-externally-defined-symbols to override";
532 Error(StrBuf.str());
533 }
534
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800535 // Converts function declarations into constant value IDs.
536 void createValueIDsForFunctions() {
Karl Schimpf57d31ac2015-10-07 09:53:12 -0700537 Ice::GlobalContext *Ctx = getTranslator().getContext();
Karl Schimpf209318a2015-08-20 13:24:02 -0700538 for (const Ice::FunctionDeclaration *Func : FunctionDeclarations) {
Karl Schimpfa313a122015-10-08 10:40:57 -0700539 if (!Func->verifyLinkageCorrect(Ctx))
540 reportLinkageError("Function", *Func);
Jim Stichnoth0d4fc922015-12-13 21:36:33 -0800541 Ice::Constant *C = getConstantSym(
542 Func->getName(), Func->getSuppressMangling(), Func->isProto());
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800543 ValueIDConstants.push_back(C);
544 }
545 }
546
547 // Converts global variable declarations into constant value IDs.
548 void createValueIDsForGlobalVars() {
Karl Schimpf57d31ac2015-10-07 09:53:12 -0700549 Ice::GlobalContext *Ctx = getTranslator().getContext();
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800550 for (const Ice::VariableDeclaration *Decl : *VariableDeclarations) {
Karl Schimpfa313a122015-10-08 10:40:57 -0700551 if (!Decl->verifyLinkageCorrect(Ctx))
552 reportLinkageError("Global", *Decl);
Jim Stichnoth0d4fc922015-12-13 21:36:33 -0800553 Ice::Constant *C =
554 getConstantSym(Decl->getName(), Decl->getSuppressMangling(),
555 !Decl->hasInitializer());
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800556 ValueIDConstants.push_back(C);
557 }
558 }
559
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700560 // Reports that type ID is undefined, or not of the WantedType.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700561 void reportBadTypeIDAs(NaClBcIndexSize_t ID, const ExtendedType *Ty,
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700562 ExtendedType::TypeKind WantedType);
Karl Schimpfd6064a12014-08-27 15:34:58 -0700563
Andrew Scull57e12682015-09-16 11:30:19 -0700564 // Reports that there is no function declaration for ID. Returns an error
565 // recovery value to use.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700566 Ice::FunctionDeclaration *reportGetFunctionByIDError(NaClBcIndexSize_t ID);
Karl Schimpf9d98d792014-10-13 15:01:08 -0700567
Andrew Scull57e12682015-09-16 11:30:19 -0700568 // Reports that there is not global variable declaration for ID. Returns an
569 // error recovery value to use.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700570 Ice::VariableDeclaration *
571 reportGetGlobalVariableByIDError(NaClBcIndexSize_t Index);
Karl Schimpf9d98d792014-10-13 15:01:08 -0700572
Andrew Scull57e12682015-09-16 11:30:19 -0700573 // Reports that there is no corresponding ICE type for LLVMTy, and returns
574 // Ice::IceType_void.
Karl Schimpfd6064a12014-08-27 15:34:58 -0700575 Ice::Type convertToIceTypeError(Type *LLVMTy);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700576};
577
Karl Schimpf17b1a132015-03-12 09:32:06 -0700578bool TopLevelParser::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit,
579 const std::string &Message) {
Jim Stichnothfa4efea2015-01-27 05:06:03 -0800580 ErrorStatus.assign(Ice::EC_Bitcode);
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800581 ++NumErrors;
Karl Schimpf819d7b52015-01-22 10:00:07 -0800582 Ice::GlobalContext *Context = Translator.getContext();
Karl Schimpfd8b32892015-04-16 15:47:25 -0700583 { // Lock while printing out error message.
584 Ice::OstreamLocker L(Context);
Karl Schimpf2f67b922015-04-22 15:20:16 -0700585 raw_ostream &OldErrStream = setErrStream(Context->getStrError());
Karl Schimpfd8b32892015-04-16 15:47:25 -0700586 NaClBitcodeParser::ErrorAt(Level, Bit, Message);
587 setErrStream(OldErrStream);
588 }
Jan Voungf644a4b2015-03-19 11:57:52 -0700589 if (Level >= naclbitc::Error &&
590 !Translator.getFlags().getAllowErrorRecovery())
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800591 Fatal();
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800592 return true;
593}
594
Karl Schimpf74cd8832015-06-23 11:05:01 -0700595void TopLevelParser::reportBadTypeIDAs(NaClBcIndexSize_t ID,
596 const ExtendedType *Ty,
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700597 ExtendedType::TypeKind WantedType) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700598 std::string Buffer;
599 raw_string_ostream StrBuf(Buffer);
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700600 if (Ty == nullptr) {
601 StrBuf << "Can't find extended type for type id: " << ID;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700602 } else {
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700603 StrBuf << "Type id " << ID << " not " << WantedType << ". Found: " << *Ty;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700604 }
Karl Schimpf74cd8832015-06-23 11:05:01 -0700605 blockError(StrBuf.str());
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700606}
607
Karl Schimpf9d98d792014-10-13 15:01:08 -0700608Ice::FunctionDeclaration *
Karl Schimpf74cd8832015-06-23 11:05:01 -0700609TopLevelParser::reportGetFunctionByIDError(NaClBcIndexSize_t ID) {
Karl Schimpf9d98d792014-10-13 15:01:08 -0700610 std::string Buffer;
611 raw_string_ostream StrBuf(Buffer);
612 StrBuf << "Function index " << ID
613 << " not allowed. Out of range. Must be less than "
Karl Schimpf209318a2015-08-20 13:24:02 -0700614 << FunctionDeclarations.size();
Karl Schimpf74cd8832015-06-23 11:05:01 -0700615 blockError(StrBuf.str());
Karl Schimpf209318a2015-08-20 13:24:02 -0700616 if (!FunctionDeclarations.empty())
617 return FunctionDeclarations[0];
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800618 Fatal();
Karl Schimpf9d98d792014-10-13 15:01:08 -0700619}
620
621Ice::VariableDeclaration *
Karl Schimpf74cd8832015-06-23 11:05:01 -0700622TopLevelParser::reportGetGlobalVariableByIDError(NaClBcIndexSize_t Index) {
Karl Schimpf9d98d792014-10-13 15:01:08 -0700623 std::string Buffer;
624 raw_string_ostream StrBuf(Buffer);
625 StrBuf << "Global index " << Index
626 << " not allowed. Out of range. Must be less than "
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800627 << VariableDeclarations->size();
Karl Schimpf74cd8832015-06-23 11:05:01 -0700628 blockError(StrBuf.str());
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -0800629 if (!VariableDeclarations->empty())
630 return VariableDeclarations->at(0);
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800631 Fatal();
Karl Schimpf9d98d792014-10-13 15:01:08 -0700632}
633
Karl Schimpfd6064a12014-08-27 15:34:58 -0700634Ice::Type TopLevelParser::convertToIceTypeError(Type *LLVMTy) {
635 std::string Buffer;
636 raw_string_ostream StrBuf(Buffer);
637 StrBuf << "Invalid LLVM type: " << *LLVMTy;
638 Error(StrBuf.str());
639 return Ice::IceType_void;
640}
641
Karl Schimpfbba77682016-01-15 07:33:15 -0800642void TopLevelParser::verifyFunctionTypeSignatures() {
643 const Ice::GlobalContext *Ctx = getTranslator().getContext();
644 for (Ice::FunctionDeclaration *FuncDecl : FunctionDeclarations) {
645 if (!FuncDecl->validateTypeSignature(Ctx))
646 Error(FuncDecl->getTypeSignatureError(Ctx));
647 }
648}
649
Andrew Scull57e12682015-09-16 11:30:19 -0700650// Base class for parsing blocks within the bitcode file. Note: Because this is
651// the base class of block parsers, we generate error messages if ParseBlock or
652// ParseRecord is not overridden in derived classes.
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700653class BlockParserBaseClass : public NaClBitcodeParser {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800654 BlockParserBaseClass() = delete;
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800655 BlockParserBaseClass(const BlockParserBaseClass &) = delete;
656 BlockParserBaseClass &operator=(const BlockParserBaseClass &) = delete;
657
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700658public:
659 // Constructor for the top-level module block parser.
660 BlockParserBaseClass(unsigned BlockID, TopLevelParser *Context)
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800661 : NaClBitcodeParser(BlockID, Context), Context(Context) {
662 Context->setBlockParser(this);
663 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700664
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800665 ~BlockParserBaseClass() override { Context->setBlockParser(nullptr); }
666
667 // Returns the printable name of the type of block being parsed.
668 virtual const char *getBlockName() const {
669 // If this class is used, it is parsing an unknown block.
670 return "unknown";
671 }
672
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800673 // Generates an error Message with the Bit address prefixed to it.
Karl Schimpf17b1a132015-03-12 09:32:06 -0700674 bool ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit,
675 const std::string &Message) final;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700676
677protected:
678 // The context parser that contains the decoded state.
679 TopLevelParser *Context;
680
681 // Constructor for nested block parsers.
682 BlockParserBaseClass(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
683 : NaClBitcodeParser(BlockID, EnclosingParser),
684 Context(EnclosingParser->Context) {}
685
Karl Schimpfd6064a12014-08-27 15:34:58 -0700686 // Gets the translator associated with the bitcode parser.
Karl Schimpf6ff33d22014-09-22 10:28:42 -0700687 Ice::Translator &getTranslator() const { return Context->getTranslator(); }
688
689 const Ice::ClFlags &getFlags() const { return getTranslator().getFlags(); }
Karl Schimpfd6064a12014-08-27 15:34:58 -0700690
Andrew Scull57e12682015-09-16 11:30:19 -0700691 // Default implementation. Reports that block is unknown and skips its
692 // contents.
Jim Stichnoth8e8042c2014-09-25 17:51:47 -0700693 bool ParseBlock(unsigned BlockID) override;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700694
Andrew Scull57e12682015-09-16 11:30:19 -0700695 // Default implementation. Reports that the record is not understood.
Jim Stichnoth8e8042c2014-09-25 17:51:47 -0700696 void ProcessRecord() override;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700697
Andrew Scull57e12682015-09-16 11:30:19 -0700698 // Checks if the size of the record is Size. Return true if valid. Otherwise
699 // generates an error and returns false.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700700 bool isValidRecordSize(size_t Size, const char *RecordName) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700701 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
Karl Schimpfd6064a12014-08-27 15:34:58 -0700702 if (Values.size() == Size)
703 return true;
Karl Schimpf74cd8832015-06-23 11:05:01 -0700704 reportRecordSizeError(Size, RecordName, nullptr);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700705 return false;
706 }
707
Andrew Scull57e12682015-09-16 11:30:19 -0700708 // Checks if the size of the record is at least as large as the LowerLimit.
709 // Returns true if valid. Otherwise generates an error and returns false.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700710 bool isValidRecordSizeAtLeast(size_t LowerLimit, const char *RecordName) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700711 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
Karl Schimpfd6064a12014-08-27 15:34:58 -0700712 if (Values.size() >= LowerLimit)
713 return true;
Karl Schimpf74cd8832015-06-23 11:05:01 -0700714 reportRecordSizeError(LowerLimit, RecordName, "at least");
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700715 return false;
716 }
717
Karl Schimpfd6064a12014-08-27 15:34:58 -0700718 // Checks if the size of the record is no larger than the
Andrew Scull57e12682015-09-16 11:30:19 -0700719 // UpperLimit. Returns true if valid. Otherwise generates an error and
720 // returns false.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700721 bool isValidRecordSizeAtMost(size_t UpperLimit, const char *RecordName) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700722 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
Karl Schimpfd6064a12014-08-27 15:34:58 -0700723 if (Values.size() <= UpperLimit)
724 return true;
Karl Schimpf74cd8832015-06-23 11:05:01 -0700725 reportRecordSizeError(UpperLimit, RecordName, "no more than");
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700726 return false;
727 }
728
Andrew Scull57e12682015-09-16 11:30:19 -0700729 // Checks if the size of the record is at least as large as the LowerLimit,
730 // and no larger than the UpperLimit. Returns true if valid. Otherwise
731 // generates an error and returns false.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700732 bool isValidRecordSizeInRange(size_t LowerLimit, size_t UpperLimit,
Karl Schimpfd6064a12014-08-27 15:34:58 -0700733 const char *RecordName) {
734 return isValidRecordSizeAtLeast(LowerLimit, RecordName) ||
735 isValidRecordSizeAtMost(UpperLimit, RecordName);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700736 }
737
738private:
Andrew Scull57e12682015-09-16 11:30:19 -0700739 /// Generates a record size error. ExpectedSize is the number of elements
740 /// expected. RecordName is the name of the kind of record that has incorrect
741 /// size. ContextMessage (if not nullptr) is appended to "record expects" to
742 /// describe how ExpectedSize should be interpreted.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700743 void reportRecordSizeError(size_t ExpectedSize, const char *RecordName,
Karl Schimpfd6064a12014-08-27 15:34:58 -0700744 const char *ContextMessage);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700745};
746
Karl Schimpf74cd8832015-06-23 11:05:01 -0700747bool TopLevelParser::blockError(const std::string &Message) {
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800748 if (BlockParser)
749 return BlockParser->Error(Message);
750 else
751 return Error(Message);
752}
753
754// Generates an error Message with the bit address prefixed to it.
Jan Voungf644a4b2015-03-19 11:57:52 -0700755bool BlockParserBaseClass::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit,
756 const std::string &Message) {
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800757 std::string Buffer;
758 raw_string_ostream StrBuf(Buffer);
Andrew Scull57e12682015-09-16 11:30:19 -0700759 // Note: If dump routines have been turned off, the error messages will not
760 // be readable. Hence, replace with simple error. We also use the simple form
761 // for unit tests.
Karl Schimpfdf80eb82015-02-09 14:20:22 -0800762 if (getFlags().getGenerateUnitTestMessages()) {
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800763 StrBuf << "Invalid " << getBlockName() << " record: <" << Record.GetCode();
764 for (const uint64_t Val : Record.GetValues()) {
765 StrBuf << " " << Val;
766 }
767 StrBuf << ">";
Karl Schimpfdf80eb82015-02-09 14:20:22 -0800768 } else {
769 StrBuf << Message;
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800770 }
Karl Schimpf17b1a132015-03-12 09:32:06 -0700771 return Context->ErrorAt(Level, Bit, StrBuf.str());
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800772}
773
Karl Schimpf74cd8832015-06-23 11:05:01 -0700774void BlockParserBaseClass::reportRecordSizeError(size_t ExpectedSize,
Karl Schimpfd6064a12014-08-27 15:34:58 -0700775 const char *RecordName,
776 const char *ContextMessage) {
777 std::string Buffer;
778 raw_string_ostream StrBuf(Buffer);
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800779 const char *BlockName = getBlockName();
780 const char FirstChar = toupper(*BlockName);
781 StrBuf << FirstChar << (BlockName + 1) << " " << RecordName
782 << " record expects";
Karl Schimpfd6064a12014-08-27 15:34:58 -0700783 if (ContextMessage)
784 StrBuf << " " << ContextMessage;
785 StrBuf << " " << ExpectedSize << " argument";
786 if (ExpectedSize > 1)
787 StrBuf << "s";
788 StrBuf << ". Found: " << Record.GetValues().size();
789 Error(StrBuf.str());
790}
791
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700792bool BlockParserBaseClass::ParseBlock(unsigned BlockID) {
Andrew Scull57e12682015-09-16 11:30:19 -0700793 // If called, derived class doesn't know how to handle block. Report error
794 // and skip.
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700795 std::string Buffer;
796 raw_string_ostream StrBuf(Buffer);
797 StrBuf << "Don't know how to parse block id: " << BlockID;
798 Error(StrBuf.str());
799 SkipBlock();
800 return false;
801}
802
803void BlockParserBaseClass::ProcessRecord() {
804 // If called, derived class doesn't know how to handle.
805 std::string Buffer;
806 raw_string_ostream StrBuf(Buffer);
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800807 StrBuf << "Don't know how to process " << getBlockName()
808 << " record:" << Record;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700809 Error(StrBuf.str());
810}
811
812// Class to parse a types block.
813class TypesParser : public BlockParserBaseClass {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800814 TypesParser() = delete;
815 TypesParser(const TypesParser &) = delete;
816 TypesParser &operator=(const TypesParser &) = delete;
817
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700818public:
819 TypesParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
Karl Schimpf58455872014-11-03 11:29:39 -0800820 : BlockParserBaseClass(BlockID, EnclosingParser),
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700821 Timer(Ice::TimerStack::TT_parseTypes, getTranslator().getContext()) {}
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700822
Karl Schimpf74cd8832015-06-23 11:05:01 -0700823 ~TypesParser() override {
824 if (ExpectedNumTypes != Context->getNumTypeIDValues()) {
825 std::string Buffer;
826 raw_string_ostream StrBuf(Buffer);
827 StrBuf << "Types block expected " << ExpectedNumTypes
828 << " types but found: " << NextTypeId;
829 Error(StrBuf.str());
830 }
831 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700832
833private:
Karl Schimpf58455872014-11-03 11:29:39 -0800834 Ice::TimerMarker Timer;
Andrew Scull57e12682015-09-16 11:30:19 -0700835 // The type ID that will be associated with the next type defining record in
836 // the types block.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700837 NaClBcIndexSize_t NextTypeId = 0;
838
839 // The expected number of types, based on record TYPE_CODE_NUMENTRY.
840 NaClBcIndexSize_t ExpectedNumTypes = 0;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700841
Jim Stichnoth8e8042c2014-09-25 17:51:47 -0700842 void ProcessRecord() override;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700843
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800844 const char *getBlockName() const override { return "type"; }
845
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700846 void setNextTypeIDAsSimpleType(Ice::Type Ty) {
847 Context->getTypeByIDForDefining(NextTypeId++)->setAsSimpleType(Ty);
848 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700849};
850
851void TypesParser::ProcessRecord() {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700852 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
853 switch (Record.GetCode()) {
Karl Schimpf74cd8832015-06-23 11:05:01 -0700854 case naclbitc::TYPE_CODE_NUMENTRY: {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700855 // NUMENTRY: [numentries]
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800856 if (!isValidRecordSize(1, "count"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700857 return;
Karl Schimpf74cd8832015-06-23 11:05:01 -0700858 uint64_t Size = Values[0];
859 if (Size > NaClBcIndexSize_t_Max) {
860 std::string Buffer;
861 raw_string_ostream StrBuf(Buffer);
862 StrBuf << "Size to big for count record: " << Size;
863 Error(StrBuf.str());
864 ExpectedNumTypes = NaClBcIndexSize_t_Max;
865 }
Andrew Scull57e12682015-09-16 11:30:19 -0700866 // The code double checks that Expected size and the actual size at the end
867 // of the block. To reduce allocations we preallocate the space.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700868 //
Andrew Scull57e12682015-09-16 11:30:19 -0700869 // However, if the number is large, we suspect that the number is
870 // (possibly) incorrect. In that case, we preallocate a smaller space.
Karl Schimpf74cd8832015-06-23 11:05:01 -0700871 constexpr uint64_t DefaultLargeResizeValue = 1000000;
872 Context->resizeTypeIDValues(std::min(Size, DefaultLargeResizeValue));
873 ExpectedNumTypes = Size;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700874 return;
Karl Schimpf74cd8832015-06-23 11:05:01 -0700875 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700876 case naclbitc::TYPE_CODE_VOID:
877 // VOID
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800878 if (!isValidRecordSize(0, "void"))
Karl Schimpfd6064a12014-08-27 15:34:58 -0700879 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700880 setNextTypeIDAsSimpleType(Ice::IceType_void);
881 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700882 case naclbitc::TYPE_CODE_FLOAT:
883 // FLOAT
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800884 if (!isValidRecordSize(0, "float"))
Karl Schimpfd6064a12014-08-27 15:34:58 -0700885 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700886 setNextTypeIDAsSimpleType(Ice::IceType_f32);
887 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700888 case naclbitc::TYPE_CODE_DOUBLE:
889 // DOUBLE
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800890 if (!isValidRecordSize(0, "double"))
Karl Schimpfd6064a12014-08-27 15:34:58 -0700891 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700892 setNextTypeIDAsSimpleType(Ice::IceType_f64);
893 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700894 case naclbitc::TYPE_CODE_INTEGER:
895 // INTEGER: [width]
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800896 if (!isValidRecordSize(1, "integer"))
Karl Schimpfd6064a12014-08-27 15:34:58 -0700897 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700898 switch (Values[0]) {
899 case 1:
900 setNextTypeIDAsSimpleType(Ice::IceType_i1);
901 return;
902 case 8:
903 setNextTypeIDAsSimpleType(Ice::IceType_i8);
904 return;
905 case 16:
906 setNextTypeIDAsSimpleType(Ice::IceType_i16);
907 return;
908 case 32:
909 setNextTypeIDAsSimpleType(Ice::IceType_i32);
910 return;
911 case 64:
912 setNextTypeIDAsSimpleType(Ice::IceType_i64);
913 return;
914 default:
915 break;
916 }
917 {
Karl Schimpfd6064a12014-08-27 15:34:58 -0700918 std::string Buffer;
919 raw_string_ostream StrBuf(Buffer);
920 StrBuf << "Type integer record with invalid bitsize: " << Values[0];
921 Error(StrBuf.str());
Karl Schimpfd6064a12014-08-27 15:34:58 -0700922 }
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700923 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -0700924 case naclbitc::TYPE_CODE_VECTOR: {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700925 // VECTOR: [numelts, eltty]
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800926 if (!isValidRecordSize(2, "vector"))
Karl Schimpfd6064a12014-08-27 15:34:58 -0700927 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700928 Ice::Type BaseTy = Context->getSimpleTypeByID(Values[1]);
929 Ice::SizeT Size = Values[0];
930 switch (BaseTy) {
931 case Ice::IceType_i1:
932 switch (Size) {
933 case 4:
934 setNextTypeIDAsSimpleType(Ice::IceType_v4i1);
935 return;
936 case 8:
937 setNextTypeIDAsSimpleType(Ice::IceType_v8i1);
938 return;
939 case 16:
940 setNextTypeIDAsSimpleType(Ice::IceType_v16i1);
941 return;
942 default:
943 break;
944 }
945 break;
946 case Ice::IceType_i8:
947 if (Size == 16) {
948 setNextTypeIDAsSimpleType(Ice::IceType_v16i8);
949 return;
950 }
951 break;
952 case Ice::IceType_i16:
953 if (Size == 8) {
954 setNextTypeIDAsSimpleType(Ice::IceType_v8i16);
955 return;
956 }
957 break;
958 case Ice::IceType_i32:
959 if (Size == 4) {
960 setNextTypeIDAsSimpleType(Ice::IceType_v4i32);
961 return;
962 }
963 break;
964 case Ice::IceType_f32:
965 if (Size == 4) {
966 setNextTypeIDAsSimpleType(Ice::IceType_v4f32);
967 return;
968 }
969 break;
970 default:
971 break;
972 }
973 {
Karl Schimpfd6064a12014-08-27 15:34:58 -0700974 std::string Buffer;
975 raw_string_ostream StrBuf(Buffer);
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700976 StrBuf << "Invalid type vector record: <" << Values[0] << " x " << BaseTy
Karl Schimpfd6064a12014-08-27 15:34:58 -0700977 << ">";
978 Error(StrBuf.str());
Karl Schimpfd6064a12014-08-27 15:34:58 -0700979 }
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700980 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -0700981 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700982 case naclbitc::TYPE_CODE_FUNCTION: {
983 // FUNCTION: [vararg, retty, paramty x N]
Karl Schimpf2f6f8602014-12-01 13:39:00 -0800984 if (!isValidRecordSizeAtLeast(2, "signature"))
Karl Schimpfd6064a12014-08-27 15:34:58 -0700985 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700986 if (Values[0])
987 Error("Function type can't define varargs");
988 ExtendedType *Ty = Context->getTypeByIDForDefining(NextTypeId++);
989 Ty->setAsFunctionType();
Jim Stichnoth54f3d512015-12-11 09:53:00 -0800990 auto *FuncTy = cast<FuncSigExtendedType>(Ty);
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700991 FuncTy->setReturnType(Context->getSimpleTypeByID(Values[1]));
Karl Schimpf74cd8832015-06-23 11:05:01 -0700992 for (size_t i = 2, e = Values.size(); i != e; ++i) {
Andrew Scull57e12682015-09-16 11:30:19 -0700993 // Check that type void not used as argument type. Note: PNaCl
994 // restrictions can't be checked until we know the name, because we have
995 // to check for intrinsic signatures.
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700996 Ice::Type ArgTy = Context->getSimpleTypeByID(Values[i]);
997 if (ArgTy == Ice::IceType_void) {
998 std::string Buffer;
999 raw_string_ostream StrBuf(Buffer);
1000 StrBuf << "Type for parameter " << (i - 1)
1001 << " not valid. Found: " << ArgTy;
Karl Schimpf645aa1a2014-10-08 09:05:53 -07001002 ArgTy = Ice::IceType_i32;
1003 }
1004 FuncTy->appendArgType(ArgTy);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001005 }
Karl Schimpf645aa1a2014-10-08 09:05:53 -07001006 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001007 }
1008 default:
1009 BlockParserBaseClass::ProcessRecord();
Karl Schimpfd6064a12014-08-27 15:34:58 -07001010 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001011 }
Karl Schimpf645aa1a2014-10-08 09:05:53 -07001012 llvm_unreachable("Unknown type block record not processed!");
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001013}
1014
Karl Schimpf9d98d792014-10-13 15:01:08 -07001015/// Parses the globals block (i.e. global variable declarations and
1016/// corresponding initializers).
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001017class GlobalsParser : public BlockParserBaseClass {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001018 GlobalsParser() = delete;
1019 GlobalsParser(const GlobalsParser &) = delete;
1020 GlobalsParser &operator=(const GlobalsParser &) = delete;
1021
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001022public:
1023 GlobalsParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
Karl Schimpf58455872014-11-03 11:29:39 -08001024 : BlockParserBaseClass(BlockID, EnclosingParser),
1025 Timer(Ice::TimerStack::TT_parseGlobals, getTranslator().getContext()),
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001026 NumFunctionIDs(Context->getNumFunctionIDs()),
John Porto1bec8bc2015-06-22 10:51:13 -07001027 DummyGlobalVar(
1028 Ice::VariableDeclaration::create(getTranslator().getContext())),
Karl Schimpf9d98d792014-10-13 15:01:08 -07001029 CurGlobalVar(DummyGlobalVar) {}
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001030
Jim Stichnothe587d942015-06-22 15:49:04 -07001031 ~GlobalsParser() final = default;
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08001032
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001033 const char *getBlockName() const override { return "globals"; }
1034
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001035private:
Andrew Scull8072bae2015-09-14 16:01:26 -07001036 using GlobalVarsMapType =
1037 std::unordered_map<NaClBcIndexSize_t, Ice::VariableDeclaration *>;
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001038
Karl Schimpf58455872014-11-03 11:29:39 -08001039 Ice::TimerMarker Timer;
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001040
1041 // Holds global variables generated/referenced in the global variables block.
1042 GlobalVarsMapType GlobalVarsMap;
1043
1044 // Holds the number of defined function IDs.
1045 NaClBcIndexSize_t NumFunctionIDs;
1046
Andrew Scull57e12682015-09-16 11:30:19 -07001047 // Holds the specified number of global variables by the count record in the
1048 // global variables block.
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001049 NaClBcIndexSize_t SpecifiedNumberVars = 0;
1050
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001051 // Keeps track of how many initializers are expected for the global variable
Karl Schimpf9d98d792014-10-13 15:01:08 -07001052 // declaration being built.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001053 NaClBcIndexSize_t InitializersNeeded = 0;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001054
Karl Schimpf9d98d792014-10-13 15:01:08 -07001055 // The index of the next global variable declaration.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001056 NaClBcIndexSize_t NextGlobalID = 0;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001057
Andrew Scull57e12682015-09-16 11:30:19 -07001058 // Dummy global variable declaration to guarantee CurGlobalVar is always
1059 // defined (allowing code to not need to check if CurGlobalVar is nullptr).
Karl Schimpf9d98d792014-10-13 15:01:08 -07001060 Ice::VariableDeclaration *DummyGlobalVar;
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001061
Karl Schimpf9d98d792014-10-13 15:01:08 -07001062 // Holds the current global variable declaration being built.
1063 Ice::VariableDeclaration *CurGlobalVar;
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001064
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001065 // Returns the global variable associated with the given Index.
1066 Ice::VariableDeclaration *getGlobalVarByID(NaClBcIndexSize_t Index) {
1067 Ice::VariableDeclaration *&Decl = GlobalVarsMap[Index];
1068 if (Decl == nullptr)
1069 Decl = Ice::VariableDeclaration::create(getTranslator().getContext());
1070 return Decl;
1071 }
1072
1073 // Returns the global declaration associated with the given index.
1074 Ice::GlobalDeclaration *getGlobalDeclByID(NaClBcIndexSize_t Index) {
1075 if (Index < NumFunctionIDs)
1076 return Context->getFunctionByID(Index);
1077 return getGlobalVarByID(Index - NumFunctionIDs);
1078 }
1079
1080 // If global variables parsed correctly, install them into the top-level
1081 // context.
1082 void installGlobalVariables() {
1083 // Verify specified number of globals matches number found.
1084 size_t NumGlobals = GlobalVarsMap.size();
1085 if (SpecifiedNumberVars != NumGlobals ||
1086 SpecifiedNumberVars != NextGlobalID) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001087 std::string Buffer;
1088 raw_string_ostream StrBuf(Buffer);
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001089 StrBuf << getBlockName() << " block expects " << SpecifiedNumberVars
1090 << " global variables. Found: " << GlobalVarsMap.size();
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001091 Error(StrBuf.str());
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001092 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001093 }
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001094 // Install global variables into top-level context.
1095 for (size_t I = 0; I < NumGlobals; ++I)
1096 Context->addGlobalDeclaration(GlobalVarsMap[I]);
1097 }
1098
1099 void ExitBlock() override {
1100 verifyNoMissingInitializers();
1101 installGlobalVariables();
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001102 BlockParserBaseClass::ExitBlock();
1103 }
1104
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07001105 void ProcessRecord() override;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001106
Karl Schimpf9d98d792014-10-13 15:01:08 -07001107 // Checks if the number of initializers for the CurGlobalVar is the same as
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001108 // the number found in the bitcode file. If different, and error message is
1109 // generated, and the internal state of the parser is fixed so this condition
1110 // is no longer violated.
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001111 void verifyNoMissingInitializers() {
Karl Schimpf9d98d792014-10-13 15:01:08 -07001112 size_t NumInits = CurGlobalVar->getInitializers().size();
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001113 if (InitializersNeeded != NumInits) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001114 std::string Buffer;
1115 raw_string_ostream StrBuf(Buffer);
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001116 StrBuf << "Global variable @g" << NextGlobalID << " expected "
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001117 << InitializersNeeded << " initializer";
1118 if (InitializersNeeded > 1)
1119 StrBuf << "s";
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001120 StrBuf << ". Found: " << NumInits;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001121 Error(StrBuf.str());
Karl Schimpf9d98d792014-10-13 15:01:08 -07001122 InitializersNeeded = NumInits;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001123 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001124 }
1125};
1126
1127void GlobalsParser::ProcessRecord() {
1128 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1129 switch (Record.GetCode()) {
1130 case naclbitc::GLOBALVAR_COUNT:
1131 // COUNT: [n]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001132 if (!isValidRecordSize(1, "count"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001133 return;
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001134 if (SpecifiedNumberVars || NextGlobalID) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001135 Error("Globals count record not first in block.");
1136 return;
1137 }
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001138 SpecifiedNumberVars = Values[0];
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001139 return;
1140 case naclbitc::GLOBALVAR_VAR: {
1141 // VAR: [align, isconst]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001142 if (!isValidRecordSize(2, "variable"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001143 return;
1144 verifyNoMissingInitializers();
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001145 // Always build the global variable, even if IR generation is turned off.
1146 // This is needed because we need a placeholder in the top-level context
1147 // when no IR is generated.
Karl Schimpf07af2ac2015-09-30 15:33:41 -07001148 uint32_t Alignment =
1149 Context->extractAlignment(this, "Global variable", Values[0]);
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001150 CurGlobalVar = getGlobalVarByID(NextGlobalID);
Jim Stichnoth0d4fc922015-12-13 21:36:33 -08001151 InitializersNeeded = 1;
1152 CurGlobalVar->setAlignment(Alignment);
1153 CurGlobalVar->setIsConstant(Values[1] != 0);
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001154 ++NextGlobalID;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001155 return;
1156 }
1157 case naclbitc::GLOBALVAR_COMPOUND:
1158 // COMPOUND: [size]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001159 if (!isValidRecordSize(1, "compound"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001160 return;
Karl Schimpf9d98d792014-10-13 15:01:08 -07001161 if (!CurGlobalVar->getInitializers().empty()) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001162 Error("Globals compound record not first initializer");
1163 return;
1164 }
1165 if (Values[0] < 2) {
1166 std::string Buffer;
1167 raw_string_ostream StrBuf(Buffer);
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001168 StrBuf << getBlockName()
1169 << " compound record size invalid. Found: " << Values[0];
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001170 Error(StrBuf.str());
1171 return;
1172 }
1173 InitializersNeeded = Values[0];
1174 return;
1175 case naclbitc::GLOBALVAR_ZEROFILL: {
1176 // ZEROFILL: [size]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001177 if (!isValidRecordSize(1, "zerofill"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001178 return;
Karl Schimpf9d98d792014-10-13 15:01:08 -07001179 CurGlobalVar->addInitializer(
John Porto1bec8bc2015-06-22 10:51:13 -07001180 Ice::VariableDeclaration::ZeroInitializer::create(Values[0]));
Karl Schimpf9d98d792014-10-13 15:01:08 -07001181 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001182 }
1183 case naclbitc::GLOBALVAR_DATA: {
1184 // DATA: [b0, b1, ...]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001185 if (!isValidRecordSizeAtLeast(1, "data"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001186 return;
Karl Schimpf9d98d792014-10-13 15:01:08 -07001187 CurGlobalVar->addInitializer(
John Porto1bec8bc2015-06-22 10:51:13 -07001188 Ice::VariableDeclaration::DataInitializer::create(Values));
Karl Schimpf9d98d792014-10-13 15:01:08 -07001189 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001190 }
1191 case naclbitc::GLOBALVAR_RELOC: {
1192 // RELOC: [val, [addend]]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001193 if (!isValidRecordSizeInRange(1, 2, "reloc"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001194 return;
Karl Schimpfaa0ce792015-08-07 09:28:57 -07001195 NaClBcIndexSize_t Index = Values[0];
1196 NaClBcIndexSize_t IndexLimit = SpecifiedNumberVars + NumFunctionIDs;
1197 if (Index >= IndexLimit) {
1198 std::string Buffer;
1199 raw_string_ostream StrBuf(Buffer);
1200 StrBuf << "Relocation index " << Index << " to big. Expect index < "
1201 << IndexLimit;
1202 Error(StrBuf.str());
1203 }
Karl Schimpf74cd8832015-06-23 11:05:01 -07001204 uint64_t Offset = 0;
1205 if (Values.size() == 2) {
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001206 Offset = Values[1];
Karl Schimpf74cd8832015-06-23 11:05:01 -07001207 if (Offset > std::numeric_limits<uint32_t>::max()) {
1208 std::string Buffer;
1209 raw_string_ostream StrBuf(Buffer);
1210 StrBuf << "Addend of global reloc record too big: " << Offset;
1211 Error(StrBuf.str());
1212 }
1213 }
John Porto844211e2016-02-04 08:42:48 -08001214 Ice::GlobalContext *Ctx = getTranslator().getContext();
John Porto1bec8bc2015-06-22 10:51:13 -07001215 CurGlobalVar->addInitializer(
1216 Ice::VariableDeclaration::RelocInitializer::create(
John Porto844211e2016-02-04 08:42:48 -08001217 getGlobalDeclByID(Index), {Ice::RelocOffset::create(Ctx, Offset)}));
Karl Schimpf9d98d792014-10-13 15:01:08 -07001218 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001219 }
1220 default:
1221 BlockParserBaseClass::ProcessRecord();
1222 return;
1223 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001224}
1225
Karl Schimpfc132b762014-09-11 09:43:47 -07001226/// Base class for parsing a valuesymtab block in the bitcode file.
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001227class ValuesymtabParser : public BlockParserBaseClass {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001228 ValuesymtabParser() = delete;
Jim Stichnoth0795ba02014-10-01 14:23:01 -07001229 ValuesymtabParser(const ValuesymtabParser &) = delete;
1230 void operator=(const ValuesymtabParser &) = delete;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001231
1232public:
Karl Schimpfc132b762014-09-11 09:43:47 -07001233 ValuesymtabParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
1234 : BlockParserBaseClass(BlockID, EnclosingParser) {}
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001235
Jim Stichnothe587d942015-06-22 15:49:04 -07001236 ~ValuesymtabParser() override = default;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001237
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001238 const char *getBlockName() const override { return "valuesymtab"; }
1239
Karl Schimpfc132b762014-09-11 09:43:47 -07001240protected:
Andrew Scull8072bae2015-09-14 16:01:26 -07001241 using StringType = SmallString<128>;
Karl Schimpfc132b762014-09-11 09:43:47 -07001242
Karl Schimpf52863b12015-09-16 13:51:21 -07001243 // Returns the name to identify the kind of symbol table this is
1244 // in error messages.
1245 virtual const char *getTableKind() const = 0;
1246
Karl Schimpfc132b762014-09-11 09:43:47 -07001247 // Associates Name with the value defined by the given Index.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001248 virtual void setValueName(NaClBcIndexSize_t Index, StringType &Name) = 0;
Karl Schimpfc132b762014-09-11 09:43:47 -07001249
1250 // Associates Name with the value defined by the given Index;
Karl Schimpf74cd8832015-06-23 11:05:01 -07001251 virtual void setBbName(NaClBcIndexSize_t Index, StringType &Name) = 0;
Karl Schimpfc132b762014-09-11 09:43:47 -07001252
Karl Schimpf52863b12015-09-16 13:51:21 -07001253 // Reports that the assignment of Name to the value associated with
1254 // index is not possible, for the given Context.
1255 void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index,
1256 StringType &Name);
1257
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001258private:
Karl Schimpf52863b12015-09-16 13:51:21 -07001259 using NamesSetType = std::unordered_set<StringType>;
1260 NamesSetType ValueNames;
1261 NamesSetType BlockNames;
1262
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07001263 void ProcessRecord() override;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001264
Karl Schimpf52863b12015-09-16 13:51:21 -07001265 // Extracts out ConvertedName. Returns true if unique wrt to Names.
1266 bool convertToString(NamesSetType &Names, StringType &ConvertedName) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001267 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1268 for (size_t i = 1, e = Values.size(); i != e; ++i) {
1269 ConvertedName += static_cast<char>(Values[i]);
1270 }
Karl Schimpf52863b12015-09-16 13:51:21 -07001271 auto Pair = Names.insert(ConvertedName);
1272 return Pair.second;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001273 }
Karl Schimpf52863b12015-09-16 13:51:21 -07001274
1275 void ReportDuplicateName(const char *NameCat, StringType &Name);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001276};
1277
Karl Schimpf52863b12015-09-16 13:51:21 -07001278void ValuesymtabParser::reportUnableToAssign(const char *Context,
1279 NaClBcIndexSize_t Index,
1280 StringType &Name) {
1281 std::string Buffer;
1282 raw_string_ostream StrBuf(Buffer);
1283 StrBuf << getTableKind() << " " << getBlockName() << ": " << Context
1284 << " name '" << Name << "' can't be associated with index " << Index;
1285 Error(StrBuf.str());
1286}
1287
1288void ValuesymtabParser::ReportDuplicateName(const char *NameCat,
1289 StringType &Name) {
1290 std::string Buffer;
1291 raw_string_ostream StrBuf(Buffer);
1292 StrBuf << getTableKind() << " " << getBlockName() << " defines duplicate "
1293 << NameCat << " name: '" << Name << "'";
1294 Error(StrBuf.str());
1295}
1296
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001297void ValuesymtabParser::ProcessRecord() {
1298 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1299 StringType ConvertedName;
1300 switch (Record.GetCode()) {
1301 case naclbitc::VST_CODE_ENTRY: {
1302 // VST_ENTRY: [ValueId, namechar x N]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001303 if (!isValidRecordSizeAtLeast(2, "value entry"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001304 return;
Karl Schimpf52863b12015-09-16 13:51:21 -07001305 if (convertToString(ValueNames, ConvertedName))
1306 setValueName(Values[0], ConvertedName);
1307 else
1308 ReportDuplicateName("value", ConvertedName);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001309 return;
1310 }
1311 case naclbitc::VST_CODE_BBENTRY: {
1312 // VST_BBENTRY: [BbId, namechar x N]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001313 if (!isValidRecordSizeAtLeast(2, "basic block entry"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001314 return;
Karl Schimpf52863b12015-09-16 13:51:21 -07001315 if (convertToString(BlockNames, ConvertedName))
1316 setBbName(Values[0], ConvertedName);
1317 else
1318 ReportDuplicateName("block", ConvertedName);
Karl Schimpfc132b762014-09-11 09:43:47 -07001319 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001320 }
1321 default:
1322 break;
1323 }
1324 // If reached, don't know how to handle record.
1325 BlockParserBaseClass::ProcessRecord();
1326 return;
1327}
1328
Karl Schimpfd6064a12014-08-27 15:34:58 -07001329/// Parses function blocks in the bitcode file.
1330class FunctionParser : public BlockParserBaseClass {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001331 FunctionParser() = delete;
Jim Stichnoth0795ba02014-10-01 14:23:01 -07001332 FunctionParser(const FunctionParser &) = delete;
1333 FunctionParser &operator=(const FunctionParser &) = delete;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001334
1335public:
1336 FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
1337 : BlockParserBaseClass(BlockID, EnclosingParser),
Karl Schimpf58455872014-11-03 11:29:39 -08001338 Timer(Ice::TimerStack::TT_parseFunctions, getTranslator().getContext()),
Jim Stichnotheafb56c2015-06-22 10:35:22 -07001339 Func(nullptr), FcnId(Context->getNextFunctionBlockValueID()),
Karl Schimpf9d98d792014-10-13 15:01:08 -07001340 FuncDecl(Context->getFunctionByID(FcnId)),
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001341 CachedNumGlobalValueIDs(Context->getNumGlobalIDs()),
Jim Stichnotheafb56c2015-06-22 10:35:22 -07001342 NextLocalInstIndex(Context->getNumGlobalIDs()) {}
Jim Stichnoth8e928382015-02-02 17:03:08 -08001343
1344 bool convertFunction() {
1345 const Ice::TimerStackIdT StackID = Ice::GlobalContext::TSK_Funcs;
1346 Ice::TimerIdT TimerID = 0;
Karl Schimpfdf80eb82015-02-09 14:20:22 -08001347 const bool TimeThisFunction = getFlags().getTimeEachFunction();
Jim Stichnoth8e928382015-02-02 17:03:08 -08001348 if (TimeThisFunction) {
1349 TimerID = getTranslator().getContext()->getTimerID(StackID,
1350 FuncDecl->getName());
1351 getTranslator().getContext()->pushTimer(TimerID, StackID);
1352 }
1353
Andrew Scull57e12682015-09-16 11:30:19 -07001354 // Note: The Cfg is created, even when IR generation is disabled. This is
1355 // done to install a CfgLocalAllocator for various internal containers.
Karl Schimpf209318a2015-08-20 13:24:02 -07001356 Func = Ice::Cfg::create(getTranslator().getContext(),
1357 getTranslator().getNextSequenceNumber());
Jim Stichnoth8e928382015-02-02 17:03:08 -08001358 Ice::Cfg::setCurrentCfg(Func.get());
1359
Andrew Scull57e12682015-09-16 11:30:19 -07001360 // TODO(kschimpf) Clean up API to add a function signature to a CFG.
Karl Schimpf9d98d792014-10-13 15:01:08 -07001361 const Ice::FuncSigType &Signature = FuncDecl->getSignature();
Jim Stichnoth0d4fc922015-12-13 21:36:33 -08001362
1363 Func->setFunctionName(FuncDecl->getName());
1364 Func->setReturnType(Signature.getReturnType());
1365 Func->setInternal(FuncDecl->getLinkage() == GlobalValue::InternalLinkage);
1366 CurrentNode = installNextBasicBlock();
1367 Func->setEntryNode(CurrentNode);
1368 for (Ice::Type ArgType : Signature.getArgList()) {
1369 Func->addArg(getNextInstVar(ArgType));
Karl Schimpfd6064a12014-08-27 15:34:58 -07001370 }
Jim Stichnoth0d4fc922015-12-13 21:36:33 -08001371
Jim Stichnoth8e928382015-02-02 17:03:08 -08001372 bool ParserResult = ParseThisBlock();
1373
Andrew Scull57e12682015-09-16 11:30:19 -07001374 // Temporarily end per-function timing, which will be resumed by the
1375 // translator function. This is because translation may be done
1376 // asynchronously in a separate thread.
Jim Stichnoth8e928382015-02-02 17:03:08 -08001377 if (TimeThisFunction)
1378 getTranslator().getContext()->popTimer(TimerID, StackID);
1379
1380 Ice::Cfg::setCurrentCfg(nullptr);
Andrew Scull57e12682015-09-16 11:30:19 -07001381 // Note: Once any errors have been found, we turn off all translation of
1382 // all remaining functions. This allows successive parsing errors to be
1383 // reported, without adding extra checks to the translator for such parsing
1384 // errors.
Jim Stichnothbbca7542015-02-11 16:08:31 -08001385 if (Context->getNumErrors() == 0 && Func) {
Jim Stichnoth8e928382015-02-02 17:03:08 -08001386 getTranslator().translateFcn(std::move(Func));
1387 // The translator now has ownership of Func.
1388 } else {
1389 Func.reset();
1390 }
1391
1392 return ParserResult;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001393 }
1394
Jim Stichnothe587d942015-06-22 15:49:04 -07001395 ~FunctionParser() final = default;
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08001396
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001397 const char *getBlockName() const override { return "function"; }
1398
Jim Stichnoth8e928382015-02-02 17:03:08 -08001399 Ice::Cfg *getFunc() const { return Func.get(); }
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001400
Karl Schimpf74cd8832015-06-23 11:05:01 -07001401 size_t getNumGlobalIDs() const { return CachedNumGlobalValueIDs; }
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001402
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08001403 void setNextLocalInstIndex(Ice::Operand *Op) {
1404 setOperand(NextLocalInstIndex++, Op);
1405 }
Karl Schimpfd6064a12014-08-27 15:34:58 -07001406
Karl Schimpff12355e2014-09-08 13:41:09 -07001407 // Set the next constant ID to the given constant C.
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08001408 void setNextConstantID(Ice::Constant *C) { setNextLocalInstIndex(C); }
Karl Schimpff12355e2014-09-08 13:41:09 -07001409
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001410 // Returns the value referenced by the given value Index.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001411 Ice::Operand *getOperand(NaClBcIndexSize_t Index) {
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001412 if (Index < CachedNumGlobalValueIDs) {
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -08001413 return Context->getGlobalConstantByID(Index);
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001414 }
Karl Schimpf74cd8832015-06-23 11:05:01 -07001415 NaClBcIndexSize_t LocalIndex = Index - CachedNumGlobalValueIDs;
Karl Schimpf9d25e622015-09-16 13:47:01 -07001416 if (LocalIndex >= LocalOperands.size())
1417 reportGetOperandUndefined(Index);
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001418 Ice::Operand *Op = LocalOperands[LocalIndex];
Karl Schimpf9d25e622015-09-16 13:47:01 -07001419 if (Op == nullptr)
1420 reportGetOperandUndefined(Index);
Karl Schimpf2f6f8602014-12-01 13:39:00 -08001421 return Op;
1422 }
1423
Karl Schimpfd6064a12014-08-27 15:34:58 -07001424private:
Karl Schimpf58455872014-11-03 11:29:39 -08001425 Ice::TimerMarker Timer;
Karl Schimpf98ed4462015-08-14 13:08:42 -07001426 // The number of words in the bitstream defining the function block.
1427 uint64_t NumBytesDefiningFunction = 0;
Karl Schimpf7a993272015-08-17 12:43:29 -07001428 // Maximum number of records that can appear in the function block, based on
1429 // the number of bytes defining the function block.
1430 uint64_t MaxRecordsInBlock = 0;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001431 // The corresponding ICE function defined by the function block.
Jim Stichnoth8e928382015-02-02 17:03:08 -08001432 std::unique_ptr<Ice::Cfg> Func;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001433 // The index to the current basic block being built.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001434 NaClBcIndexSize_t CurrentBbIndex = 0;
Karl Schimpf98ed4462015-08-14 13:08:42 -07001435 // The number of basic blocks declared for the function block.
1436 NaClBcIndexSize_t DeclaredNumberBbs = 0;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001437 // The basic block being built.
Jim Stichnotheafb56c2015-06-22 10:35:22 -07001438 Ice::CfgNode *CurrentNode = nullptr;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001439 // The ID for the function.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001440 NaClBcIndexSize_t FcnId;
Karl Schimpf9d98d792014-10-13 15:01:08 -07001441 // The corresponding function declaration.
1442 Ice::FunctionDeclaration *FuncDecl;
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001443 // Holds the dividing point between local and global absolute value indices.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001444 size_t CachedNumGlobalValueIDs;
Andrew Scull57e12682015-09-16 11:30:19 -07001445 // Holds operands local to the function block, based on indices defined in
1446 // the bitcode file.
Karl Schimpf209318a2015-08-20 13:24:02 -07001447 Ice::OperandList LocalOperands;
Andrew Scull57e12682015-09-16 11:30:19 -07001448 // Holds the index within LocalOperands corresponding to the next instruction
1449 // that generates a value.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001450 NaClBcIndexSize_t NextLocalInstIndex;
Andrew Scull57e12682015-09-16 11:30:19 -07001451 // True if the last processed instruction was a terminating instruction.
Jim Stichnotheafb56c2015-06-22 10:35:22 -07001452 bool InstIsTerminating = false;
Karl Schimpf41689df2014-09-10 14:36:07 -07001453
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07001454 bool ParseBlock(unsigned BlockID) override;
Karl Schimpff12355e2014-09-08 13:41:09 -07001455
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07001456 void ProcessRecord() override;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001457
Karl Schimpf98ed4462015-08-14 13:08:42 -07001458 void EnterBlock(unsigned NumWords) final {
1459 // Note: Bitstream defines words as 32-bit values.
1460 NumBytesDefiningFunction = NumWords * sizeof(uint32_t);
Karl Schimpf7a993272015-08-17 12:43:29 -07001461 // We know that all records are minimally defined by a two-bit abreviation.
1462 MaxRecordsInBlock = NumBytesDefiningFunction * (CHAR_BIT >> 1);
Karl Schimpf98ed4462015-08-14 13:08:42 -07001463 }
1464
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07001465 void ExitBlock() override;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001466
Karl Schimpf98ed4462015-08-14 13:08:42 -07001467 // Creates and appends a new basic block to the list of basic blocks.
1468 Ice::CfgNode *installNextBasicBlock() {
Karl Schimpf98ed4462015-08-14 13:08:42 -07001469 Ice::CfgNode *Node = Func->makeNode();
1470 return Node;
1471 }
1472
1473 // Returns the Index-th basic block in the list of basic blocks.
1474 Ice::CfgNode *getBasicBlock(NaClBcIndexSize_t Index) {
Karl Schimpf98ed4462015-08-14 13:08:42 -07001475 if (Index >= Func->getNumNodes()) {
1476 std::string Buffer;
1477 raw_string_ostream StrBuf(Buffer);
1478 StrBuf << "Reference to basic block " << Index
1479 << " not found. Must be less than " << Func->getNumNodes();
1480 Error(StrBuf.str());
1481 Index = 0;
1482 }
1483 return Func->getNodes()[Index];
1484 }
1485
Andrew Scull57e12682015-09-16 11:30:19 -07001486 // Returns the Index-th basic block in the list of basic blocks. Assumes
1487 // Index corresponds to a branch instruction. Hence, if the branch references
1488 // the entry block, it also generates a corresponding error.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001489 Ice::CfgNode *getBranchBasicBlock(NaClBcIndexSize_t Index) {
Karl Schimpfc836acb2014-09-05 08:32:47 -07001490 if (Index == 0) {
1491 Error("Branch to entry block not allowed");
Karl Schimpfc836acb2014-09-05 08:32:47 -07001492 }
Karl Schimpf47661562014-09-11 14:42:49 -07001493 return getBasicBlock(Index);
Karl Schimpfc836acb2014-09-05 08:32:47 -07001494 }
1495
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001496 // Generate an instruction variable with type Ty.
1497 Ice::Variable *createInstVar(Ice::Type Ty) {
Karl Schimpf47661562014-09-11 14:42:49 -07001498 if (Ty == Ice::IceType_void) {
1499 Error("Can't define instruction value using type void");
1500 // Recover since we can't throw an exception.
1501 Ty = Ice::IceType_i32;
1502 }
Jim Stichnoth144cdce2014-09-22 16:02:59 -07001503 return Func->makeVariable(Ty);
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001504 }
1505
1506 // Generates the next available local variable using the given type.
1507 Ice::Variable *getNextInstVar(Ice::Type Ty) {
1508 assert(NextLocalInstIndex >= CachedNumGlobalValueIDs);
1509 // Before creating one, see if a forwardtyperef has already defined it.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001510 NaClBcIndexSize_t LocalIndex = NextLocalInstIndex - CachedNumGlobalValueIDs;
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001511 if (LocalIndex < LocalOperands.size()) {
1512 Ice::Operand *Op = LocalOperands[LocalIndex];
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001513 if (Op != nullptr) {
Jim Stichnoth54f3d512015-12-11 09:53:00 -08001514 if (auto *Var = dyn_cast<Ice::Variable>(Op)) {
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001515 if (Var->getType() == Ty) {
1516 ++NextLocalInstIndex;
1517 return Var;
1518 }
1519 }
1520 std::string Buffer;
1521 raw_string_ostream StrBuf(Buffer);
1522 StrBuf << "Illegal forward referenced instruction ("
1523 << NextLocalInstIndex << "): " << *Op;
1524 Error(StrBuf.str());
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001525 ++NextLocalInstIndex;
1526 return createInstVar(Ty);
1527 }
1528 }
1529 Ice::Variable *Var = createInstVar(Ty);
1530 setOperand(NextLocalInstIndex++, Var);
Karl Schimpfd6064a12014-08-27 15:34:58 -07001531 return Var;
1532 }
1533
Andrew Scull57e12682015-09-16 11:30:19 -07001534 // Converts a relative index (wrt to BaseIndex) to an absolute value index.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001535 NaClBcIndexSize_t convertRelativeToAbsIndex(NaClRelBcIndexSize_t Id,
1536 NaClRelBcIndexSize_t BaseIndex) {
Karl Schimpf47661562014-09-11 14:42:49 -07001537 if (BaseIndex < Id) {
Karl Schimpfd6064a12014-08-27 15:34:58 -07001538 std::string Buffer;
1539 raw_string_ostream StrBuf(Buffer);
1540 StrBuf << "Invalid relative value id: " << Id
Karl Schimpf47661562014-09-11 14:42:49 -07001541 << " (must be <= " << BaseIndex << ")";
Karl Schimpfd6064a12014-08-27 15:34:58 -07001542 Error(StrBuf.str());
Karl Schimpfd6064a12014-08-27 15:34:58 -07001543 return 0;
1544 }
Karl Schimpf47661562014-09-11 14:42:49 -07001545 return BaseIndex - Id;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001546 }
1547
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001548 // Sets element Index (in the local operands list) to Op.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001549 void setOperand(NaClBcIndexSize_t Index, Ice::Operand *Op) {
Jim Stichnoth0d4fc922015-12-13 21:36:33 -08001550 assert(Op);
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001551 // Check if simple push works.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001552 NaClBcIndexSize_t LocalIndex = Index - CachedNumGlobalValueIDs;
Karl Schimpf7a993272015-08-17 12:43:29 -07001553 if (LocalIndex == LocalOperands.size()) {
1554 LocalOperands.push_back(Op);
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001555 return;
1556 }
1557
Karl Schimpf7a993272015-08-17 12:43:29 -07001558 // Must be forward reference, expand vector to accommodate.
1559 if (LocalIndex >= LocalOperands.size()) {
1560 if (LocalIndex > MaxRecordsInBlock) {
1561 std::string Buffer;
1562 raw_string_ostream StrBuf(Buffer);
1563 StrBuf << "Forward reference @" << Index << " too big. Have "
1564 << CachedNumGlobalValueIDs << " globals and function contains "
1565 << NumBytesDefiningFunction << " bytes";
1566 Fatal(StrBuf.str());
1567 // Recover by using index one beyond the maximal allowed.
1568 LocalIndex = MaxRecordsInBlock;
1569 }
1570 LocalOperands.resize(LocalIndex + 1);
1571 }
1572
1573 // If element not defined, set it.
1574 Ice::Operand *OldOp = LocalOperands[LocalIndex];
1575 if (OldOp == nullptr) {
1576 LocalOperands[LocalIndex] = Op;
1577 return;
1578 }
1579
1580 // See if forward reference matches.
1581 if (OldOp == Op)
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001582 return;
1583
1584 // Error has occurred.
1585 std::string Buffer;
1586 raw_string_ostream StrBuf(Buffer);
Karl Schimpfd1a971a2014-09-17 15:38:17 -07001587 StrBuf << "Multiple definitions for index " << Index << ": " << *Op
Karl Schimpf7a993272015-08-17 12:43:29 -07001588 << " and " << *OldOp;
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001589 Error(StrBuf.str());
Karl Schimpf7a993272015-08-17 12:43:29 -07001590 LocalOperands[LocalIndex] = Op;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001591 }
1592
Andrew Scull57e12682015-09-16 11:30:19 -07001593 // Returns the relative operand (wrt to BaseIndex) referenced by the given
1594 // value Index.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001595 Ice::Operand *getRelativeOperand(NaClBcIndexSize_t Index,
1596 NaClBcIndexSize_t BaseIndex) {
Karl Schimpf47661562014-09-11 14:42:49 -07001597 return getOperand(convertRelativeToAbsIndex(Index, BaseIndex));
1598 }
1599
1600 // Returns the absolute index of the next value generating instruction.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001601 NaClBcIndexSize_t getNextInstIndex() const { return NextLocalInstIndex; }
Karl Schimpf71ba8222014-09-03 09:46:24 -07001602
Andrew Scull57e12682015-09-16 11:30:19 -07001603 // Generates type error message for binary operator Op operating on Type
1604 // OpTy.
Karl Schimpf74cd8832015-06-23 11:05:01 -07001605 void reportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy);
Karl Schimpfd6064a12014-08-27 15:34:58 -07001606
Andrew Scull57e12682015-09-16 11:30:19 -07001607 // Validates if integer logical Op, for type OpTy, is valid. Returns true if
1608 // valid. Otherwise generates error message and returns false.
Karl Schimpfd6064a12014-08-27 15:34:58 -07001609 bool isValidIntegerLogicalOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
1610 if (Ice::isIntegerType(OpTy))
1611 return true;
Karl Schimpf74cd8832015-06-23 11:05:01 -07001612 reportInvalidBinaryOp(Op, OpTy);
Karl Schimpfd6064a12014-08-27 15:34:58 -07001613 return false;
1614 }
1615
Andrew Scull57e12682015-09-16 11:30:19 -07001616 // Validates if integer (or vector of integers) arithmetic Op, for type OpTy,
1617 // is valid. Returns true if valid. Otherwise generates error message and
1618 // returns false.
Karl Schimpfd6064a12014-08-27 15:34:58 -07001619 bool isValidIntegerArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
1620 if (Ice::isIntegerArithmeticType(OpTy))
1621 return true;
Karl Schimpf74cd8832015-06-23 11:05:01 -07001622 reportInvalidBinaryOp(Op, OpTy);
Karl Schimpfd6064a12014-08-27 15:34:58 -07001623 return false;
1624 }
1625
Andrew Scull57e12682015-09-16 11:30:19 -07001626 // Checks if floating arithmetic Op, for type OpTy, is valid. Returns true if
1627 // valid. Otherwise generates an error message and returns false;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001628 bool isValidFloatingArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
1629 if (Ice::isFloatingType(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 the type of operand Op is the valid pointer type, for the given
1636 // InstructionName. Returns true if valid. Otherwise generates an error
1637 // message and returns false.
Karl Schimpf41689df2014-09-10 14:36:07 -07001638 bool isValidPointerType(Ice::Operand *Op, const char *InstructionName) {
Karl Schimpf4019f082014-12-15 13:45:00 -08001639 Ice::Type PtrType = Ice::getPointerType();
Karl Schimpf41689df2014-09-10 14:36:07 -07001640 if (Op->getType() == PtrType)
1641 return true;
1642 std::string Buffer;
1643 raw_string_ostream StrBuf(Buffer);
1644 StrBuf << InstructionName << " address not " << PtrType
Karl Schimpffc0a52d2015-09-28 11:22:55 -07001645 << ". Found: " << Op->getType();
Karl Schimpf41689df2014-09-10 14:36:07 -07001646 Error(StrBuf.str());
1647 return false;
1648 }
1649
Andrew Scull57e12682015-09-16 11:30:19 -07001650 // Checks if loading/storing a value of type Ty is allowed. Returns true if
1651 // Valid. Otherwise generates an error message and returns false.
Karl Schimpf41689df2014-09-10 14:36:07 -07001652 bool isValidLoadStoreType(Ice::Type Ty, const char *InstructionName) {
1653 if (isLoadStoreType(Ty))
1654 return true;
1655 std::string Buffer;
1656 raw_string_ostream StrBuf(Buffer);
1657 StrBuf << InstructionName << " type not allowed: " << Ty << "*";
1658 Error(StrBuf.str());
1659 return false;
1660 }
1661
Andrew Scull57e12682015-09-16 11:30:19 -07001662 // Checks if loading/storing a value of type Ty is allowed for the given
1663 // Alignment. Otherwise generates an error message and returns false.
Karl Schimpff875d452014-12-09 13:50:07 -08001664 bool isValidLoadStoreAlignment(size_t Alignment, Ice::Type Ty,
Karl Schimpf41689df2014-09-10 14:36:07 -07001665 const char *InstructionName) {
1666 if (!isValidLoadStoreType(Ty, InstructionName))
1667 return false;
Karl Schimpff875d452014-12-09 13:50:07 -08001668 if (isAllowedAlignment(Alignment, Ty))
Karl Schimpf41689df2014-09-10 14:36:07 -07001669 return true;
1670 std::string Buffer;
1671 raw_string_ostream StrBuf(Buffer);
1672 StrBuf << InstructionName << " " << Ty << "*: not allowed for alignment "
1673 << Alignment;
1674 Error(StrBuf.str());
1675 return false;
1676 }
1677
Karl Schimpff875d452014-12-09 13:50:07 -08001678 // Defines if the given alignment is valid for the given type. Simplified
Andrew Scull57e12682015-09-16 11:30:19 -07001679 // version of PNaClABIProps::isAllowedAlignment, based on API's offered for
1680 // Ice::Type.
Karl Schimpff875d452014-12-09 13:50:07 -08001681 bool isAllowedAlignment(size_t Alignment, Ice::Type Ty) const {
1682 return Alignment == typeAlignInBytes(Ty) ||
1683 (Alignment == 1 && !isVectorType(Ty));
1684 }
1685
Karl Schimpfaff9fa22014-10-29 14:32:07 -07001686 // Types of errors that can occur for insertelement and extractelement
1687 // instructions.
1688 enum VectorIndexCheckValue {
1689 VectorIndexNotVector,
1690 VectorIndexNotConstant,
1691 VectorIndexNotInRange,
1692 VectorIndexNotI32,
1693 VectorIndexValid
1694 };
1695
1696 void dumpVectorIndexCheckValue(raw_ostream &Stream,
1697 VectorIndexCheckValue Value) const {
Jim Stichnoth20b71f52015-06-24 15:52:24 -07001698 if (!Ice::BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -08001699 return;
Karl Schimpfaff9fa22014-10-29 14:32:07 -07001700 switch (Value) {
Karl Schimpfaff9fa22014-10-29 14:32:07 -07001701 case VectorIndexNotVector:
1702 Stream << "Vector index on non vector";
1703 break;
1704 case VectorIndexNotConstant:
1705 Stream << "Vector index not integer constant";
1706 break;
1707 case VectorIndexNotInRange:
1708 Stream << "Vector index not in range of vector";
1709 break;
1710 case VectorIndexNotI32:
1711 Stream << "Vector index not of type " << Ice::IceType_i32;
1712 break;
1713 case VectorIndexValid:
1714 Stream << "Valid vector index";
1715 break;
1716 }
1717 }
1718
1719 // Returns whether the given vector index (for insertelement and
1720 // extractelement instructions) is valid.
1721 VectorIndexCheckValue validateVectorIndex(const Ice::Operand *Vec,
1722 const Ice::Operand *Index) const {
1723 Ice::Type VecType = Vec->getType();
1724 if (!Ice::isVectorType(VecType))
1725 return VectorIndexNotVector;
1726 const auto *C = dyn_cast<Ice::ConstantInteger32>(Index);
1727 if (C == nullptr)
1728 return VectorIndexNotConstant;
Jim Stichnothd2cb4362014-11-20 11:24:42 -08001729 if (static_cast<size_t>(C->getValue()) >= typeNumElements(VecType))
Karl Schimpfaff9fa22014-10-29 14:32:07 -07001730 return VectorIndexNotInRange;
1731 if (Index->getType() != Ice::IceType_i32)
1732 return VectorIndexNotI32;
1733 return VectorIndexValid;
1734 }
1735
Andrew Scull57e12682015-09-16 11:30:19 -07001736 // Takes the PNaCl bitcode binary operator Opcode, and the opcode type Ty,
1737 // and sets Op to the corresponding ICE binary opcode. Returns true if able
1738 // to convert, false otherwise.
Karl Schimpfd6064a12014-08-27 15:34:58 -07001739 bool convertBinopOpcode(unsigned Opcode, Ice::Type Ty,
1740 Ice::InstArithmetic::OpKind &Op) {
Karl Schimpf9bb188d2014-12-10 12:54:34 -08001741 switch (Opcode) {
Karl Schimpfd6064a12014-08-27 15:34:58 -07001742 default: {
Karl Schimpf9bb188d2014-12-10 12:54:34 -08001743 std::string Buffer;
1744 raw_string_ostream StrBuf(Buffer);
1745 StrBuf << "Binary opcode " << Opcode << "not understood for type " << Ty;
1746 Error(StrBuf.str());
Karl Schimpfd6064a12014-08-27 15:34:58 -07001747 Op = Ice::InstArithmetic::Add;
1748 return false;
1749 }
Karl Schimpf9bb188d2014-12-10 12:54:34 -08001750 case naclbitc::BINOP_ADD:
1751 if (Ice::isIntegerType(Ty)) {
1752 Op = Ice::InstArithmetic::Add;
1753 return isValidIntegerArithOp(Op, Ty);
1754 } else {
1755 Op = Ice::InstArithmetic::Fadd;
1756 return isValidFloatingArithOp(Op, Ty);
1757 }
1758 case naclbitc::BINOP_SUB:
1759 if (Ice::isIntegerType(Ty)) {
1760 Op = Ice::InstArithmetic::Sub;
1761 return isValidIntegerArithOp(Op, Ty);
1762 } else {
1763 Op = Ice::InstArithmetic::Fsub;
1764 return isValidFloatingArithOp(Op, Ty);
1765 }
1766 case naclbitc::BINOP_MUL:
1767 if (Ice::isIntegerType(Ty)) {
1768 Op = Ice::InstArithmetic::Mul;
1769 return isValidIntegerArithOp(Op, Ty);
1770 } else {
1771 Op = Ice::InstArithmetic::Fmul;
1772 return isValidFloatingArithOp(Op, Ty);
1773 }
1774 case naclbitc::BINOP_UDIV:
Karl Schimpfd6064a12014-08-27 15:34:58 -07001775 Op = Ice::InstArithmetic::Udiv;
1776 return isValidIntegerArithOp(Op, Ty);
Karl Schimpf9bb188d2014-12-10 12:54:34 -08001777 case naclbitc::BINOP_SDIV:
1778 if (Ice::isIntegerType(Ty)) {
1779 Op = Ice::InstArithmetic::Sdiv;
1780 return isValidIntegerArithOp(Op, Ty);
1781 } else {
1782 Op = Ice::InstArithmetic::Fdiv;
1783 return isValidFloatingArithOp(Op, Ty);
1784 }
1785 case naclbitc::BINOP_UREM:
Karl Schimpfd6064a12014-08-27 15:34:58 -07001786 Op = Ice::InstArithmetic::Urem;
1787 return isValidIntegerArithOp(Op, Ty);
Karl Schimpf9bb188d2014-12-10 12:54:34 -08001788 case naclbitc::BINOP_SREM:
1789 if (Ice::isIntegerType(Ty)) {
1790 Op = Ice::InstArithmetic::Srem;
1791 return isValidIntegerArithOp(Op, Ty);
1792 } else {
1793 Op = Ice::InstArithmetic::Frem;
1794 return isValidFloatingArithOp(Op, Ty);
1795 }
1796 case naclbitc::BINOP_SHL:
Karl Schimpfd6064a12014-08-27 15:34:58 -07001797 Op = Ice::InstArithmetic::Shl;
1798 return isValidIntegerArithOp(Op, Ty);
Karl Schimpf9bb188d2014-12-10 12:54:34 -08001799 case naclbitc::BINOP_LSHR:
Karl Schimpfd6064a12014-08-27 15:34:58 -07001800 Op = Ice::InstArithmetic::Lshr;
1801 return isValidIntegerArithOp(Op, Ty);
Karl Schimpf9bb188d2014-12-10 12:54:34 -08001802 case naclbitc::BINOP_ASHR:
Karl Schimpfd6064a12014-08-27 15:34:58 -07001803 Op = Ice::InstArithmetic::Ashr;
1804 return isValidIntegerArithOp(Op, Ty);
Karl Schimpf9bb188d2014-12-10 12:54:34 -08001805 case naclbitc::BINOP_AND:
Karl Schimpfd6064a12014-08-27 15:34:58 -07001806 Op = Ice::InstArithmetic::And;
1807 return isValidIntegerLogicalOp(Op, Ty);
Karl Schimpf9bb188d2014-12-10 12:54:34 -08001808 case naclbitc::BINOP_OR:
Karl Schimpfd6064a12014-08-27 15:34:58 -07001809 Op = Ice::InstArithmetic::Or;
1810 return isValidIntegerLogicalOp(Op, Ty);
Karl Schimpf9bb188d2014-12-10 12:54:34 -08001811 case naclbitc::BINOP_XOR:
Karl Schimpfd6064a12014-08-27 15:34:58 -07001812 Op = Ice::InstArithmetic::Xor;
1813 return isValidIntegerLogicalOp(Op, Ty);
1814 }
1815 }
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001816
Andrew Scull57e12682015-09-16 11:30:19 -07001817 /// Simplifies out vector types from Type1 and Type2, if both are vectors of
1818 /// the same size. Returns true iff both are vectors of the same size, or are
1819 /// both scalar types.
Karl Schimpfbf170372014-12-15 10:16:31 -08001820 static bool simplifyOutCommonVectorType(Ice::Type &Type1, Ice::Type &Type2) {
1821 bool IsType1Vector = isVectorType(Type1);
1822 bool IsType2Vector = isVectorType(Type2);
1823 if (IsType1Vector != IsType2Vector)
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001824 return false;
Karl Schimpfbf170372014-12-15 10:16:31 -08001825 if (!IsType1Vector)
1826 return true;
1827 if (typeNumElements(Type1) != typeNumElements(Type2))
1828 return false;
1829 Type1 = typeElementType(Type1);
1830 Type2 = typeElementType(Type2);
1831 return true;
1832 }
1833
1834 /// Returns true iff an integer truncation from SourceType to TargetType is
1835 /// valid.
1836 static bool isIntTruncCastValid(Ice::Type SourceType, Ice::Type TargetType) {
Jim Stichnothdd842db2015-01-27 12:53:53 -08001837 return Ice::isIntegerType(SourceType) && Ice::isIntegerType(TargetType) &&
1838 simplifyOutCommonVectorType(SourceType, TargetType) &&
1839 getScalarIntBitWidth(SourceType) > getScalarIntBitWidth(TargetType);
Karl Schimpfbf170372014-12-15 10:16:31 -08001840 }
1841
1842 /// Returns true iff a floating type truncation from SourceType to TargetType
1843 /// is valid.
1844 static bool isFloatTruncCastValid(Ice::Type SourceType,
1845 Ice::Type TargetType) {
Jim Stichnothdd842db2015-01-27 12:53:53 -08001846 return simplifyOutCommonVectorType(SourceType, TargetType) &&
1847 SourceType == Ice::IceType_f64 && TargetType == Ice::IceType_f32;
Karl Schimpfbf170372014-12-15 10:16:31 -08001848 }
1849
1850 /// Returns true iff an integer extension from SourceType to TargetType is
1851 /// valid.
1852 static bool isIntExtCastValid(Ice::Type SourceType, Ice::Type TargetType) {
1853 return isIntTruncCastValid(TargetType, SourceType);
1854 }
1855
1856 /// Returns true iff a floating type extension from SourceType to TargetType
1857 /// is valid.
1858 static bool isFloatExtCastValid(Ice::Type SourceType, Ice::Type TargetType) {
1859 return isFloatTruncCastValid(TargetType, SourceType);
1860 }
1861
Andrew Scull57e12682015-09-16 11:30:19 -07001862 /// Returns true iff a cast from floating type SourceType to integer type
1863 /// TargetType is valid.
Karl Schimpfbf170372014-12-15 10:16:31 -08001864 static bool isFloatToIntCastValid(Ice::Type SourceType,
1865 Ice::Type TargetType) {
1866 if (!(Ice::isFloatingType(SourceType) && Ice::isIntegerType(TargetType)))
1867 return false;
1868 bool IsSourceVector = isVectorType(SourceType);
1869 bool IsTargetVector = isVectorType(TargetType);
1870 if (IsSourceVector != IsTargetVector)
1871 return false;
1872 if (IsSourceVector) {
1873 return typeNumElements(SourceType) == typeNumElements(TargetType);
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001874 }
1875 return true;
1876 }
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07001877
Andrew Scull57e12682015-09-16 11:30:19 -07001878 /// Returns true iff a cast from integer type SourceType to floating type
1879 /// TargetType is valid.
Karl Schimpfbf170372014-12-15 10:16:31 -08001880 static bool isIntToFloatCastValid(Ice::Type SourceType,
1881 Ice::Type TargetType) {
1882 return isFloatToIntCastValid(TargetType, SourceType);
1883 }
1884
Andrew Scull57e12682015-09-16 11:30:19 -07001885 /// Returns the number of bits used to model type Ty when defining the bitcast
1886 /// instruction.
Karl Schimpfbf170372014-12-15 10:16:31 -08001887 static Ice::SizeT bitcastSizeInBits(Ice::Type Ty) {
1888 if (Ice::isVectorType(Ty))
1889 return Ice::typeNumElements(Ty) *
1890 bitcastSizeInBits(Ice::typeElementType(Ty));
1891 if (Ty == Ice::IceType_i1)
1892 return 1;
1893 return Ice::typeWidthInBytes(Ty) * CHAR_BIT;
1894 }
1895
1896 /// Returns true iff a bitcast from SourceType to TargetType is allowed.
1897 static bool isBitcastValid(Ice::Type SourceType, Ice::Type TargetType) {
1898 return bitcastSizeInBits(SourceType) == bitcastSizeInBits(TargetType);
1899 }
1900
Andrew Scull57e12682015-09-16 11:30:19 -07001901 /// Returns true iff the NaCl bitcode Opcode is a valid cast opcode for
1902 /// converting SourceType to TargetType. Updates CastKind to the corresponding
1903 /// instruction cast opcode. Also generates an error message when this
1904 /// function returns false.
Karl Schimpfbf170372014-12-15 10:16:31 -08001905 bool convertCastOpToIceOp(uint64_t Opcode, Ice::Type SourceType,
1906 Ice::Type TargetType,
1907 Ice::InstCast::OpKind &CastKind) {
1908 bool Result;
1909 switch (Opcode) {
1910 default: {
1911 std::string Buffer;
1912 raw_string_ostream StrBuf(Buffer);
1913 StrBuf << "Cast opcode " << Opcode << " not understood.\n";
1914 Error(StrBuf.str());
Karl Schimpfbf170372014-12-15 10:16:31 -08001915 CastKind = Ice::InstCast::Bitcast;
1916 return false;
1917 }
1918 case naclbitc::CAST_TRUNC:
1919 CastKind = Ice::InstCast::Trunc;
1920 Result = isIntTruncCastValid(SourceType, TargetType);
1921 break;
1922 case naclbitc::CAST_ZEXT:
1923 CastKind = Ice::InstCast::Zext;
1924 Result = isIntExtCastValid(SourceType, TargetType);
1925 break;
1926 case naclbitc::CAST_SEXT:
1927 CastKind = Ice::InstCast::Sext;
1928 Result = isIntExtCastValid(SourceType, TargetType);
1929 break;
1930 case naclbitc::CAST_FPTOUI:
1931 CastKind = Ice::InstCast::Fptoui;
1932 Result = isFloatToIntCastValid(SourceType, TargetType);
1933 break;
1934 case naclbitc::CAST_FPTOSI:
1935 CastKind = Ice::InstCast::Fptosi;
1936 Result = isFloatToIntCastValid(SourceType, TargetType);
1937 break;
1938 case naclbitc::CAST_UITOFP:
1939 CastKind = Ice::InstCast::Uitofp;
1940 Result = isIntToFloatCastValid(SourceType, TargetType);
1941 break;
1942 case naclbitc::CAST_SITOFP:
1943 CastKind = Ice::InstCast::Sitofp;
1944 Result = isIntToFloatCastValid(SourceType, TargetType);
1945 break;
1946 case naclbitc::CAST_FPTRUNC:
1947 CastKind = Ice::InstCast::Fptrunc;
1948 Result = isFloatTruncCastValid(SourceType, TargetType);
1949 break;
1950 case naclbitc::CAST_FPEXT:
1951 CastKind = Ice::InstCast::Fpext;
1952 Result = isFloatExtCastValid(SourceType, TargetType);
1953 break;
1954 case naclbitc::CAST_BITCAST:
1955 CastKind = Ice::InstCast::Bitcast;
1956 Result = isBitcastValid(SourceType, TargetType);
1957 break;
1958 }
1959 if (!Result) {
1960 std::string Buffer;
1961 raw_string_ostream StrBuf(Buffer);
1962 StrBuf << "Illegal cast: " << Ice::InstCast::getCastName(CastKind) << " "
1963 << SourceType << " to " << TargetType;
1964 Error(StrBuf.str());
1965 }
1966 return Result;
1967 }
1968
Andrew Scull57e12682015-09-16 11:30:19 -07001969 // Converts PNaCl bitcode Icmp operator to corresponding ICE op. Returns true
1970 // if able to convert, false otherwise.
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07001971 bool convertNaClBitcICmpOpToIce(uint64_t Op,
1972 Ice::InstIcmp::ICond &Cond) const {
1973 switch (Op) {
1974 case naclbitc::ICMP_EQ:
1975 Cond = Ice::InstIcmp::Eq;
1976 return true;
1977 case naclbitc::ICMP_NE:
1978 Cond = Ice::InstIcmp::Ne;
1979 return true;
1980 case naclbitc::ICMP_UGT:
1981 Cond = Ice::InstIcmp::Ugt;
1982 return true;
1983 case naclbitc::ICMP_UGE:
1984 Cond = Ice::InstIcmp::Uge;
1985 return true;
1986 case naclbitc::ICMP_ULT:
1987 Cond = Ice::InstIcmp::Ult;
1988 return true;
1989 case naclbitc::ICMP_ULE:
1990 Cond = Ice::InstIcmp::Ule;
1991 return true;
1992 case naclbitc::ICMP_SGT:
1993 Cond = Ice::InstIcmp::Sgt;
1994 return true;
1995 case naclbitc::ICMP_SGE:
1996 Cond = Ice::InstIcmp::Sge;
1997 return true;
1998 case naclbitc::ICMP_SLT:
1999 Cond = Ice::InstIcmp::Slt;
2000 return true;
2001 case naclbitc::ICMP_SLE:
2002 Cond = Ice::InstIcmp::Sle;
2003 return true;
2004 default:
Jim Stichnothdddaf9c2014-12-04 14:09:21 -08002005 // Make sure Cond is always initialized.
2006 Cond = static_cast<Ice::InstIcmp::ICond>(0);
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002007 return false;
2008 }
2009 }
2010
Andrew Scull57e12682015-09-16 11:30:19 -07002011 // Converts PNaCl bitcode Fcmp operator to corresponding ICE op. Returns true
2012 // if able to convert, false otherwise.
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002013 bool convertNaClBitcFCompOpToIce(uint64_t Op,
2014 Ice::InstFcmp::FCond &Cond) const {
2015 switch (Op) {
2016 case naclbitc::FCMP_FALSE:
2017 Cond = Ice::InstFcmp::False;
2018 return true;
2019 case naclbitc::FCMP_OEQ:
2020 Cond = Ice::InstFcmp::Oeq;
2021 return true;
2022 case naclbitc::FCMP_OGT:
2023 Cond = Ice::InstFcmp::Ogt;
2024 return true;
2025 case naclbitc::FCMP_OGE:
2026 Cond = Ice::InstFcmp::Oge;
2027 return true;
2028 case naclbitc::FCMP_OLT:
2029 Cond = Ice::InstFcmp::Olt;
2030 return true;
2031 case naclbitc::FCMP_OLE:
2032 Cond = Ice::InstFcmp::Ole;
2033 return true;
2034 case naclbitc::FCMP_ONE:
2035 Cond = Ice::InstFcmp::One;
2036 return true;
2037 case naclbitc::FCMP_ORD:
2038 Cond = Ice::InstFcmp::Ord;
2039 return true;
2040 case naclbitc::FCMP_UNO:
2041 Cond = Ice::InstFcmp::Uno;
2042 return true;
2043 case naclbitc::FCMP_UEQ:
2044 Cond = Ice::InstFcmp::Ueq;
2045 return true;
2046 case naclbitc::FCMP_UGT:
2047 Cond = Ice::InstFcmp::Ugt;
2048 return true;
2049 case naclbitc::FCMP_UGE:
2050 Cond = Ice::InstFcmp::Uge;
2051 return true;
2052 case naclbitc::FCMP_ULT:
2053 Cond = Ice::InstFcmp::Ult;
2054 return true;
2055 case naclbitc::FCMP_ULE:
2056 Cond = Ice::InstFcmp::Ule;
2057 return true;
2058 case naclbitc::FCMP_UNE:
2059 Cond = Ice::InstFcmp::Une;
2060 return true;
2061 case naclbitc::FCMP_TRUE:
2062 Cond = Ice::InstFcmp::True;
2063 return true;
2064 default:
Jim Stichnothdddaf9c2014-12-04 14:09:21 -08002065 // Make sure Cond is always initialized.
2066 Cond = static_cast<Ice::InstFcmp::FCond>(0);
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002067 return false;
2068 }
2069 }
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002070
Andrew Scull57e12682015-09-16 11:30:19 -07002071 // Creates an error instruction, generating a value of type Ty, and adds a
2072 // placeholder so that instruction indices line up. Some instructions, such
2073 // as a call, will not generate a value if the return type is void. In such
2074 // cases, a placeholder value for the badly formed instruction is not needed.
2075 // Hence, if Ty is void, an error instruction is not appended.
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002076 void appendErrorInstruction(Ice::Type Ty) {
Andrew Scull57e12682015-09-16 11:30:19 -07002077 // Note: we don't worry about downstream translation errors because the
2078 // function will not be translated if any errors occur.
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002079 if (Ty == Ice::IceType_void)
2080 return;
2081 Ice::Variable *Var = getNextInstVar(Ty);
Jim Stichnoth8e928382015-02-02 17:03:08 -08002082 CurrentNode->appendInst(Ice::InstAssign::create(Func.get(), Var, Var));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002083 }
Karl Schimpf9d25e622015-09-16 13:47:01 -07002084
2085 Ice::Operand *reportGetOperandUndefined(NaClBcIndexSize_t Index) {
2086 std::string Buffer;
2087 raw_string_ostream StrBuf(Buffer);
2088 StrBuf << "Value index " << Index << " not defined!";
Karl Schimpf43632b92015-09-21 15:32:30 -07002089 Error(StrBuf.str());
2090 // Recover and return some value.
2091 if (!LocalOperands.empty())
2092 return LocalOperands.front();
2093 return Context->getGlobalConstantByID(0);
Karl Schimpf9d25e622015-09-16 13:47:01 -07002094 }
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002095
Jim Stichnoth48e3ae52015-10-01 13:33:35 -07002096 void verifyCallArgTypeMatches(Ice::FunctionDeclaration *Fcn, Ice::SizeT Index,
2097 Ice::Type ArgType, Ice::Type ParamType) {
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002098 if (ArgType != ParamType) {
2099 std::string Buffer;
2100 raw_string_ostream StrBuf(Buffer);
Jim Stichnoth48e3ae52015-10-01 13:33:35 -07002101 StrBuf << "Argument " << (Index + 1) << " of " << printName(Fcn)
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002102 << " expects " << ParamType << ". Found: " << ArgType;
2103 Error(StrBuf.str());
2104 }
2105 }
2106
2107 const Ice::IceString printName(Ice::FunctionDeclaration *Fcn) {
2108 if (Fcn)
2109 return Fcn->getName();
2110 return "function";
2111 }
Karl Schimpfd6064a12014-08-27 15:34:58 -07002112};
2113
Karl Schimpfd6064a12014-08-27 15:34:58 -07002114void FunctionParser::ExitBlock() {
Karl Schimpf6c17dd82015-06-30 10:25:27 -07002115 // Check if the last instruction in the function was terminating.
2116 if (!InstIsTerminating) {
2117 Error("Last instruction in function not terminator");
Karl Schimpf6c17dd82015-06-30 10:25:27 -07002118 // Recover by inserting an unreachable instruction.
2119 CurrentNode->appendInst(Ice::InstUnreachable::create(Func.get()));
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002120 }
Karl Schimpf98ed4462015-08-14 13:08:42 -07002121 ++CurrentBbIndex;
2122 if (CurrentBbIndex != DeclaredNumberBbs) {
2123 std::string Buffer;
2124 raw_string_ostream StrBuf(Buffer);
2125 StrBuf << "Function declared " << DeclaredNumberBbs
2126 << " basic blocks, but defined " << CurrentBbIndex << ".";
2127 Error(StrBuf.str());
2128 }
Andrew Scull57e12682015-09-16 11:30:19 -07002129 // Before translating, check for blocks without instructions, and insert
2130 // unreachable. This shouldn't happen, but be safe.
Karl Schimpf74cd8832015-06-23 11:05:01 -07002131 size_t Index = 0;
Jim Stichnothf44f3712014-10-01 14:05:51 -07002132 for (Ice::CfgNode *Node : Func->getNodes()) {
Jim Stichnothbfb410d2014-11-05 16:04:05 -08002133 if (Node->getInsts().empty()) {
Karl Schimpfd6064a12014-08-27 15:34:58 -07002134 std::string Buffer;
2135 raw_string_ostream StrBuf(Buffer);
2136 StrBuf << "Basic block " << Index << " contains no instructions";
2137 Error(StrBuf.str());
Jim Stichnoth8e928382015-02-02 17:03:08 -08002138 Node->appendInst(Ice::InstUnreachable::create(Func.get()));
Karl Schimpfd6064a12014-08-27 15:34:58 -07002139 }
Jim Stichnothf44f3712014-10-01 14:05:51 -07002140 ++Index;
Karl Schimpfd6064a12014-08-27 15:34:58 -07002141 }
Jim Stichnoth69d3f9c2015-03-23 10:33:38 -07002142 Func->computeInOutEdges();
Karl Schimpfd6064a12014-08-27 15:34:58 -07002143}
2144
Karl Schimpf74cd8832015-06-23 11:05:01 -07002145void FunctionParser::reportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op,
Karl Schimpfd6064a12014-08-27 15:34:58 -07002146 Ice::Type OpTy) {
2147 std::string Buffer;
2148 raw_string_ostream StrBuf(Buffer);
2149 StrBuf << "Invalid operator type for " << Ice::InstArithmetic::getOpName(Op)
2150 << ". Found " << OpTy;
2151 Error(StrBuf.str());
2152}
2153
2154void FunctionParser::ProcessRecord() {
Andrew Scull57e12682015-09-16 11:30:19 -07002155 // Note: To better separate parse/IR generation times, when IR generation is
2156 // disabled we do the following:
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002157 // 1) Delay exiting until after we extract operands.
2158 // 2) return before we access operands, since all operands will be a nullptr.
Karl Schimpfd6064a12014-08-27 15:34:58 -07002159 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
2160 if (InstIsTerminating) {
2161 InstIsTerminating = false;
Karl Schimpf98ed4462015-08-14 13:08:42 -07002162 ++CurrentBbIndex;
Jim Stichnoth0d4fc922015-12-13 21:36:33 -08002163 CurrentNode = getBasicBlock(CurrentBbIndex);
Karl Schimpfd6064a12014-08-27 15:34:58 -07002164 }
Karl Schimpf47661562014-09-11 14:42:49 -07002165 // The base index for relative indexing.
Karl Schimpf74cd8832015-06-23 11:05:01 -07002166 NaClBcIndexSize_t BaseIndex = getNextInstIndex();
Karl Schimpfd6064a12014-08-27 15:34:58 -07002167 switch (Record.GetCode()) {
2168 case naclbitc::FUNC_CODE_DECLAREBLOCKS: {
2169 // DECLAREBLOCKS: [n]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002170 if (!isValidRecordSize(1, "count"))
Karl Schimpfc0fdc272014-09-02 10:47:28 -07002171 return;
Karl Schimpf98ed4462015-08-14 13:08:42 -07002172 if (DeclaredNumberBbs > 0) {
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002173 Error("Duplicate function block count record");
2174 return;
2175 }
Karl Schimpf98ed4462015-08-14 13:08:42 -07002176
Karl Schimpf98ed4462015-08-14 13:08:42 -07002177 // Check for bad large sizes, since they can make ridiculous memory
Karl Schimpf7a993272015-08-17 12:43:29 -07002178 // requests and hang the user for large amounts of time.
2179 uint64_t NumBbs = Values[0];
2180 if (NumBbs > MaxRecordsInBlock) {
Karl Schimpf98ed4462015-08-14 13:08:42 -07002181 std::string Buffer;
2182 raw_string_ostream StrBuf(Buffer);
2183 StrBuf << "Function defines " << NumBbs
2184 << " basic blocks, which is too big for a function containing "
2185 << NumBytesDefiningFunction << " bytes";
2186 Error(StrBuf.str());
Karl Schimpf7a993272015-08-17 12:43:29 -07002187 NumBbs = MaxRecordsInBlock;
Karl Schimpf98ed4462015-08-14 13:08:42 -07002188 }
2189
2190 if (NumBbs == 0) {
2191 Error("Functions must contain at least one basic block.");
2192 NumBbs = 1;
2193 }
2194
2195 DeclaredNumberBbs = NumBbs;
Karl Schimpf98ed4462015-08-14 13:08:42 -07002196 // Install the basic blocks, skipping bb0 which was created in the
2197 // constructor.
2198 for (size_t i = 1; i < NumBbs; ++i)
2199 installNextBasicBlock();
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002200 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -07002201 }
2202 case naclbitc::FUNC_CODE_INST_BINOP: {
2203 // BINOP: [opval, opval, opcode]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002204 if (!isValidRecordSize(3, "binop"))
Karl Schimpfc0fdc272014-09-02 10:47:28 -07002205 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002206 Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex);
2207 Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex);
Karl Schimpfd6064a12014-08-27 15:34:58 -07002208 Ice::Type Type1 = Op1->getType();
2209 Ice::Type Type2 = Op2->getType();
2210 if (Type1 != Type2) {
2211 std::string Buffer;
2212 raw_string_ostream StrBuf(Buffer);
2213 StrBuf << "Binop argument types differ: " << Type1 << " and " << Type2;
2214 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002215 appendErrorInstruction(Type1);
2216 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -07002217 }
2218
2219 Ice::InstArithmetic::OpKind Opcode;
Karl Schimpf9bb188d2014-12-10 12:54:34 -08002220 if (!convertBinopOpcode(Values[2], Type1, Opcode)) {
2221 appendErrorInstruction(Type1);
Karl Schimpfc0fdc272014-09-02 10:47:28 -07002222 return;
Karl Schimpf9bb188d2014-12-10 12:54:34 -08002223 }
Karl Schimpf47661562014-09-11 14:42:49 -07002224 CurrentNode->appendInst(Ice::InstArithmetic::create(
Jim Stichnoth8e928382015-02-02 17:03:08 -08002225 Func.get(), Opcode, getNextInstVar(Type1), Op1, Op2));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002226 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -07002227 }
Karl Schimpfc0fdc272014-09-02 10:47:28 -07002228 case naclbitc::FUNC_CODE_INST_CAST: {
2229 // CAST: [opval, destty, castopc]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002230 if (!isValidRecordSize(3, "cast"))
Karl Schimpfc0fdc272014-09-02 10:47:28 -07002231 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002232 Ice::Operand *Src = getRelativeOperand(Values[0], BaseIndex);
Karl Schimpf645aa1a2014-10-08 09:05:53 -07002233 Ice::Type CastType = Context->getSimpleTypeByID(Values[1]);
Karl Schimpfc0fdc272014-09-02 10:47:28 -07002234 Ice::InstCast::OpKind CastKind;
Karl Schimpfbf170372014-12-15 10:16:31 -08002235 if (!convertCastOpToIceOp(Values[2], Src->getType(), CastType, CastKind)) {
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002236 appendErrorInstruction(CastType);
Karl Schimpfc0fdc272014-09-02 10:47:28 -07002237 return;
2238 }
Jim Stichnoth8e928382015-02-02 17:03:08 -08002239 CurrentNode->appendInst(Ice::InstCast::create(
2240 Func.get(), CastKind, getNextInstVar(CastType), Src));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002241 return;
Karl Schimpfc0fdc272014-09-02 10:47:28 -07002242 }
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07002243 case naclbitc::FUNC_CODE_INST_VSELECT: {
2244 // VSELECT: [opval, opval, pred]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002245 if (!isValidRecordSize(3, "select"))
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002246 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002247 Ice::Operand *ThenVal = getRelativeOperand(Values[0], BaseIndex);
Karl Schimpf47661562014-09-11 14:42:49 -07002248 Ice::Operand *ElseVal = getRelativeOperand(Values[1], BaseIndex);
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002249 Ice::Operand *CondVal = getRelativeOperand(Values[2], BaseIndex);
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002250 Ice::Type ThenType = ThenVal->getType();
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07002251 Ice::Type ElseType = ElseVal->getType();
2252 if (ThenType != ElseType) {
2253 std::string Buffer;
2254 raw_string_ostream StrBuf(Buffer);
2255 StrBuf << "Select operands not same type. Found " << ThenType << " and "
2256 << ElseType;
2257 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002258 appendErrorInstruction(ThenType);
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07002259 return;
2260 }
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07002261 Ice::Type CondType = CondVal->getType();
2262 if (isVectorType(CondType)) {
2263 if (!isVectorType(ThenType) ||
2264 typeElementType(CondType) != Ice::IceType_i1 ||
2265 typeNumElements(ThenType) != typeNumElements(CondType)) {
2266 std::string Buffer;
2267 raw_string_ostream StrBuf(Buffer);
Karl Schimpf97501832014-09-16 13:35:32 -07002268 StrBuf << "Select condition type " << CondType
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07002269 << " not allowed for values of type " << ThenType;
2270 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002271 appendErrorInstruction(ThenType);
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07002272 return;
2273 }
2274 } else if (CondVal->getType() != Ice::IceType_i1) {
2275 std::string Buffer;
2276 raw_string_ostream StrBuf(Buffer);
Jim Stichnothdd842db2015-01-27 12:53:53 -08002277 StrBuf << "Select condition " << CondVal
2278 << " not type i1. Found: " << CondVal->getType();
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07002279 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002280 appendErrorInstruction(ThenType);
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07002281 return;
2282 }
Karl Schimpf47661562014-09-11 14:42:49 -07002283 CurrentNode->appendInst(Ice::InstSelect::create(
Jim Stichnoth8e928382015-02-02 17:03:08 -08002284 Func.get(), getNextInstVar(ThenType), CondVal, ThenVal, ElseVal));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002285 return;
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07002286 }
Karl Schimpf71ba8222014-09-03 09:46:24 -07002287 case naclbitc::FUNC_CODE_INST_EXTRACTELT: {
2288 // EXTRACTELT: [opval, opval]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002289 if (!isValidRecordSize(2, "extract element"))
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002290 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002291 Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex);
Karl Schimpf47661562014-09-11 14:42:49 -07002292 Ice::Operand *Index = getRelativeOperand(Values[1], BaseIndex);
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002293 Ice::Type VecType = Vec->getType();
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002294 VectorIndexCheckValue IndexCheckValue = validateVectorIndex(Vec, Index);
2295 if (IndexCheckValue != VectorIndexValid) {
Karl Schimpf71ba8222014-09-03 09:46:24 -07002296 std::string Buffer;
2297 raw_string_ostream StrBuf(Buffer);
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002298 dumpVectorIndexCheckValue(StrBuf, IndexCheckValue);
2299 StrBuf << ": extractelement " << VecType << " " << *Vec << ", "
2300 << Index->getType() << " " << *Index;
Karl Schimpf71ba8222014-09-03 09:46:24 -07002301 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002302 appendErrorInstruction(VecType);
2303 return;
Karl Schimpf71ba8222014-09-03 09:46:24 -07002304 }
Karl Schimpf47661562014-09-11 14:42:49 -07002305 CurrentNode->appendInst(Ice::InstExtractElement::create(
Jim Stichnoth8e928382015-02-02 17:03:08 -08002306 Func.get(), getNextInstVar(typeElementType(VecType)), Vec, Index));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002307 return;
Karl Schimpf71ba8222014-09-03 09:46:24 -07002308 }
2309 case naclbitc::FUNC_CODE_INST_INSERTELT: {
2310 // INSERTELT: [opval, opval, opval]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002311 if (!isValidRecordSize(3, "insert element"))
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002312 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002313 Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex);
Karl Schimpf47661562014-09-11 14:42:49 -07002314 Ice::Operand *Elt = getRelativeOperand(Values[1], BaseIndex);
Karl Schimpf47661562014-09-11 14:42:49 -07002315 Ice::Operand *Index = getRelativeOperand(Values[2], BaseIndex);
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002316 Ice::Type VecType = Vec->getType();
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002317 VectorIndexCheckValue IndexCheckValue = validateVectorIndex(Vec, Index);
2318 if (IndexCheckValue != VectorIndexValid) {
Karl Schimpf71ba8222014-09-03 09:46:24 -07002319 std::string Buffer;
2320 raw_string_ostream StrBuf(Buffer);
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002321 dumpVectorIndexCheckValue(StrBuf, IndexCheckValue);
2322 StrBuf << ": insertelement " << VecType << " " << *Vec << ", "
2323 << Elt->getType() << " " << *Elt << ", " << Index->getType() << " "
2324 << *Index;
Karl Schimpf71ba8222014-09-03 09:46:24 -07002325 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002326 appendErrorInstruction(Elt->getType());
2327 return;
Karl Schimpf71ba8222014-09-03 09:46:24 -07002328 }
Karl Schimpf43632b92015-09-21 15:32:30 -07002329 if (Ice::typeElementType(VecType) != Elt->getType()) {
2330 std::string Buffer;
2331 raw_string_ostream StrBuf(Buffer);
2332 StrBuf << "Insertelement: Element type "
2333 << Ice::typeString(Elt->getType()) << " doesn't match vector type "
2334 << Ice::typeString(VecType);
2335 Error(StrBuf.str());
2336 appendErrorInstruction(Elt->getType());
2337 return;
2338 }
Karl Schimpf47661562014-09-11 14:42:49 -07002339 CurrentNode->appendInst(Ice::InstInsertElement::create(
Jim Stichnoth8e928382015-02-02 17:03:08 -08002340 Func.get(), getNextInstVar(VecType), Vec, Elt, Index));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002341 return;
Karl Schimpf71ba8222014-09-03 09:46:24 -07002342 }
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002343 case naclbitc::FUNC_CODE_INST_CMP2: {
2344 // CMP2: [opval, opval, pred]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002345 if (!isValidRecordSize(3, "compare"))
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002346 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002347 Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex);
2348 Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex);
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002349 Ice::Type Op1Type = Op1->getType();
2350 Ice::Type Op2Type = Op2->getType();
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002351 Ice::Type DestType = getCompareResultType(Op1Type);
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002352 if (Op1Type != Op2Type) {
2353 std::string Buffer;
2354 raw_string_ostream StrBuf(Buffer);
Jim Stichnothdd842db2015-01-27 12:53:53 -08002355 StrBuf << "Compare argument types differ: " << Op1Type << " and "
2356 << Op2Type;
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002357 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002358 appendErrorInstruction(DestType);
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002359 Op2 = Op1;
2360 }
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002361 if (DestType == Ice::IceType_void) {
2362 std::string Buffer;
2363 raw_string_ostream StrBuf(Buffer);
2364 StrBuf << "Compare not defined for type " << Op1Type;
2365 Error(StrBuf.str());
2366 return;
2367 }
Karl Schimpf47661562014-09-11 14:42:49 -07002368 Ice::Variable *Dest = getNextInstVar(DestType);
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002369 if (isIntegerType(Op1Type)) {
2370 Ice::InstIcmp::ICond Cond;
2371 if (!convertNaClBitcICmpOpToIce(Values[2], Cond)) {
2372 std::string Buffer;
2373 raw_string_ostream StrBuf(Buffer);
2374 StrBuf << "Compare record contains unknown integer predicate index: "
2375 << Values[2];
2376 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002377 appendErrorInstruction(DestType);
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002378 }
Karl Schimpf47661562014-09-11 14:42:49 -07002379 CurrentNode->appendInst(
Jim Stichnoth8e928382015-02-02 17:03:08 -08002380 Ice::InstIcmp::create(Func.get(), Cond, Dest, Op1, Op2));
Jim Stichnothdd842db2015-01-27 12:53:53 -08002381 } else if (isFloatingType(Op1Type)) {
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002382 Ice::InstFcmp::FCond Cond;
2383 if (!convertNaClBitcFCompOpToIce(Values[2], Cond)) {
2384 std::string Buffer;
2385 raw_string_ostream StrBuf(Buffer);
2386 StrBuf << "Compare record contains unknown float predicate index: "
2387 << Values[2];
2388 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002389 appendErrorInstruction(DestType);
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002390 }
Karl Schimpf47661562014-09-11 14:42:49 -07002391 CurrentNode->appendInst(
Jim Stichnoth8e928382015-02-02 17:03:08 -08002392 Ice::InstFcmp::create(Func.get(), Cond, Dest, Op1, Op2));
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002393 } else {
2394 // Not sure this can happen, but be safe.
2395 std::string Buffer;
2396 raw_string_ostream StrBuf(Buffer);
2397 StrBuf << "Compare on type not understood: " << Op1Type;
2398 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002399 appendErrorInstruction(DestType);
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002400 return;
2401 }
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002402 return;
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07002403 }
Karl Schimpfd6064a12014-08-27 15:34:58 -07002404 case naclbitc::FUNC_CODE_INST_RET: {
2405 // RET: [opval?]
Karl Schimpf6c17dd82015-06-30 10:25:27 -07002406 InstIsTerminating = true;
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002407 if (!isValidRecordSizeInRange(0, 1, "return"))
Karl Schimpfc0fdc272014-09-02 10:47:28 -07002408 return;
Jim Stichnothbfb410d2014-11-05 16:04:05 -08002409 if (Values.empty()) {
Jim Stichnoth8e928382015-02-02 17:03:08 -08002410 CurrentNode->appendInst(Ice::InstRet::create(Func.get()));
Karl Schimpfd6064a12014-08-27 15:34:58 -07002411 } else {
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002412 Ice::Operand *RetVal = getRelativeOperand(Values[0], BaseIndex);
Jim Stichnoth8e928382015-02-02 17:03:08 -08002413 CurrentNode->appendInst(Ice::InstRet::create(Func.get(), RetVal));
Karl Schimpfd6064a12014-08-27 15:34:58 -07002414 }
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002415 return;
Karl Schimpfc836acb2014-09-05 08:32:47 -07002416 }
2417 case naclbitc::FUNC_CODE_INST_BR: {
Karl Schimpf6c17dd82015-06-30 10:25:27 -07002418 InstIsTerminating = true;
Karl Schimpfc836acb2014-09-05 08:32:47 -07002419 if (Values.size() == 1) {
2420 // BR: [bb#]
2421 Ice::CfgNode *Block = getBranchBasicBlock(Values[0]);
Karl Schimpfe3f64d02014-10-07 10:38:22 -07002422 if (Block == nullptr)
Karl Schimpfc836acb2014-09-05 08:32:47 -07002423 return;
Jim Stichnoth8e928382015-02-02 17:03:08 -08002424 CurrentNode->appendInst(Ice::InstBr::create(Func.get(), Block));
Karl Schimpfc836acb2014-09-05 08:32:47 -07002425 } else {
2426 // BR: [bb#, bb#, opval]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002427 if (!isValidRecordSize(3, "branch"))
Karl Schimpfc836acb2014-09-05 08:32:47 -07002428 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002429 Ice::Operand *Cond = getRelativeOperand(Values[2], BaseIndex);
Karl Schimpfc836acb2014-09-05 08:32:47 -07002430 if (Cond->getType() != Ice::IceType_i1) {
2431 std::string Buffer;
2432 raw_string_ostream StrBuf(Buffer);
Jim Stichnothdd842db2015-01-27 12:53:53 -08002433 StrBuf << "Branch condition " << *Cond
2434 << " not i1. Found: " << Cond->getType();
Karl Schimpfc836acb2014-09-05 08:32:47 -07002435 Error(StrBuf.str());
2436 return;
2437 }
2438 Ice::CfgNode *ThenBlock = getBranchBasicBlock(Values[0]);
2439 Ice::CfgNode *ElseBlock = getBranchBasicBlock(Values[1]);
Karl Schimpfe3f64d02014-10-07 10:38:22 -07002440 if (ThenBlock == nullptr || ElseBlock == nullptr)
Karl Schimpfc836acb2014-09-05 08:32:47 -07002441 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002442 CurrentNode->appendInst(
Jim Stichnoth8e928382015-02-02 17:03:08 -08002443 Ice::InstBr::create(Func.get(), Cond, ThenBlock, ElseBlock));
Karl Schimpfc836acb2014-09-05 08:32:47 -07002444 }
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002445 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -07002446 }
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002447 case naclbitc::FUNC_CODE_INST_SWITCH: {
2448 // SWITCH: [Condty, Cond, BbIndex, NumCases Case ...]
2449 // where Case = [1, 1, Value, BbIndex].
2450 //
Andrew Scull57e12682015-09-16 11:30:19 -07002451 // Note: Unlike most instructions, we don't infer the type of Cond, but
2452 // provide it as a separate field. There are also unnecessary data fields
2453 // (i.e. constants 1). These were not cleaned up in PNaCl bitcode because
2454 // the bitcode format was already frozen when the problem was noticed.
Karl Schimpf6c17dd82015-06-30 10:25:27 -07002455 InstIsTerminating = true;
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002456 if (!isValidRecordSizeAtLeast(4, "switch"))
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002457 return;
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002458
Karl Schimpf645aa1a2014-10-08 09:05:53 -07002459 Ice::Type CondTy = Context->getSimpleTypeByID(Values[0]);
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002460 if (!Ice::isScalarIntegerType(CondTy)) {
2461 std::string Buffer;
2462 raw_string_ostream StrBuf(Buffer);
2463 StrBuf << "Case condition must be non-wide integer. Found: " << CondTy;
2464 Error(StrBuf.str());
2465 return;
2466 }
2467 Ice::SizeT BitWidth = Ice::getScalarIntBitWidth(CondTy);
2468 Ice::Operand *Cond = getRelativeOperand(Values[1], BaseIndex);
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002469
Jim Stichnoth0d4fc922015-12-13 21:36:33 -08002470 if (CondTy != Cond->getType()) {
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002471 std::string Buffer;
2472 raw_string_ostream StrBuf(Buffer);
2473 StrBuf << "Case condition expects type " << CondTy
2474 << ". Found: " << Cond->getType();
2475 Error(StrBuf.str());
2476 return;
2477 }
Jim Stichnoth0d4fc922015-12-13 21:36:33 -08002478 Ice::CfgNode *DefaultLabel = getBranchBasicBlock(Values[2]);
Karl Schimpf0042fea2015-08-21 09:41:01 -07002479 if (DefaultLabel == nullptr)
2480 return;
Karl Schimpf74cd8832015-06-23 11:05:01 -07002481 uint64_t NumCasesRaw = Values[3];
2482 if (NumCasesRaw > std::numeric_limits<uint32_t>::max()) {
2483 std::string Buffer;
2484 raw_string_ostream StrBuf(Buffer);
2485 StrBuf << "Too many cases specified in switch: " << NumCasesRaw;
2486 Error(StrBuf.str());
2487 NumCasesRaw = std::numeric_limits<uint32_t>::max();
2488 }
2489 uint32_t NumCases = NumCasesRaw;
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002490
2491 // Now recognize each of the cases.
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002492 if (!isValidRecordSize(4 + NumCases * 4, "switch"))
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002493 return;
Karl Schimpf0042fea2015-08-21 09:41:01 -07002494 std::unique_ptr<Ice::InstSwitch> Switch(
Jim Stichnoth0d4fc922015-12-13 21:36:33 -08002495 Ice::InstSwitch::create(Func.get(), NumCases, Cond, DefaultLabel));
Jim Stichnothdd842db2015-01-27 12:53:53 -08002496 unsigned ValCaseIndex = 4; // index to beginning of case entry.
Karl Schimpf74cd8832015-06-23 11:05:01 -07002497 for (uint32_t CaseIndex = 0; CaseIndex < NumCases;
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002498 ++CaseIndex, ValCaseIndex += 4) {
Jim Stichnothdd842db2015-01-27 12:53:53 -08002499 if (Values[ValCaseIndex] != 1 || Values[ValCaseIndex + 1] != 1) {
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002500 std::string Buffer;
2501 raw_string_ostream StrBuf(Buffer);
2502 StrBuf << "Sequence [1, 1, value, label] expected for case entry "
2503 << "in switch record. (at index" << ValCaseIndex << ")";
2504 Error(StrBuf.str());
2505 return;
2506 }
Karl Schimpfa5295b02015-12-01 11:24:53 -08002507 BitcodeInt Value(BitWidth,
Karl Schimpf32817482014-12-15 09:52:26 -08002508 NaClDecodeSignRotatedValue(Values[ValCaseIndex + 2]));
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002509 Ice::CfgNode *Label = getBranchBasicBlock(Values[ValCaseIndex + 3]);
Karl Schimpf0042fea2015-08-21 09:41:01 -07002510 if (Label == nullptr)
2511 return;
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002512 Switch->addBranch(CaseIndex, Value.getSExtValue(), Label);
2513 }
Karl Schimpf0042fea2015-08-21 09:41:01 -07002514 CurrentNode->appendInst(Switch.release());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002515 return;
Karl Schimpfd1a971a2014-09-17 15:38:17 -07002516 }
Karl Schimpf97501832014-09-16 13:35:32 -07002517 case naclbitc::FUNC_CODE_INST_UNREACHABLE: {
2518 // UNREACHABLE: []
Karl Schimpf6c17dd82015-06-30 10:25:27 -07002519 InstIsTerminating = true;
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002520 if (!isValidRecordSize(0, "unreachable"))
Karl Schimpf97501832014-09-16 13:35:32 -07002521 return;
Jim Stichnoth8e928382015-02-02 17:03:08 -08002522 CurrentNode->appendInst(Ice::InstUnreachable::create(Func.get()));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002523 return;
Karl Schimpf97501832014-09-16 13:35:32 -07002524 }
Karl Schimpf47661562014-09-11 14:42:49 -07002525 case naclbitc::FUNC_CODE_INST_PHI: {
2526 // PHI: [ty, val1, bb1, ..., valN, bbN] for n >= 2.
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002527 if (!isValidRecordSizeAtLeast(3, "phi"))
Karl Schimpf47661562014-09-11 14:42:49 -07002528 return;
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002529 Ice::Type Ty = Context->getSimpleTypeByID(Values[0]);
Karl Schimpf47661562014-09-11 14:42:49 -07002530 if ((Values.size() & 0x1) == 0) {
2531 // Not an odd number of values.
2532 std::string Buffer;
2533 raw_string_ostream StrBuf(Buffer);
2534 StrBuf << "function block phi record size not valid: " << Values.size();
2535 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002536 appendErrorInstruction(Ty);
Karl Schimpf47661562014-09-11 14:42:49 -07002537 return;
2538 }
Karl Schimpf47661562014-09-11 14:42:49 -07002539 if (Ty == Ice::IceType_void) {
2540 Error("Phi record using type void not allowed");
2541 return;
2542 }
2543 Ice::Variable *Dest = getNextInstVar(Ty);
Jim Stichnoth8e928382015-02-02 17:03:08 -08002544 Ice::InstPhi *Phi =
2545 Ice::InstPhi::create(Func.get(), Values.size() >> 1, Dest);
Karl Schimpf74cd8832015-06-23 11:05:01 -07002546 for (size_t i = 1; i < Values.size(); i += 2) {
Karl Schimpf47661562014-09-11 14:42:49 -07002547 Ice::Operand *Op =
2548 getRelativeOperand(NaClDecodeSignRotatedValue(Values[i]), BaseIndex);
2549 if (Op->getType() != Ty) {
2550 std::string Buffer;
2551 raw_string_ostream StrBuf(Buffer);
Karl Schimpf97501832014-09-16 13:35:32 -07002552 StrBuf << "Value " << *Op << " not type " << Ty
2553 << " in phi instruction. Found: " << Op->getType();
Karl Schimpf47661562014-09-11 14:42:49 -07002554 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002555 appendErrorInstruction(Ty);
Karl Schimpf47661562014-09-11 14:42:49 -07002556 return;
2557 }
2558 Phi->addArgument(Op, getBasicBlock(Values[i + 1]));
2559 }
2560 CurrentNode->appendInst(Phi);
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002561 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002562 }
Karl Schimpf742d72d2014-09-09 11:40:09 -07002563 case naclbitc::FUNC_CODE_INST_ALLOCA: {
2564 // ALLOCA: [Size, align]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002565 if (!isValidRecordSize(2, "alloca"))
Karl Schimpf742d72d2014-09-09 11:40:09 -07002566 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002567 Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex);
Karl Schimpf07af2ac2015-09-30 15:33:41 -07002568 uint32_t Alignment = Context->extractAlignment(this, "Alloca", Values[1]);
Karl Schimpf4019f082014-12-15 13:45:00 -08002569 Ice::Type PtrTy = Ice::getPointerType();
Karl Schimpf742d72d2014-09-09 11:40:09 -07002570 if (ByteCount->getType() != Ice::IceType_i32) {
2571 std::string Buffer;
2572 raw_string_ostream StrBuf(Buffer);
Karl Schimpf97501832014-09-16 13:35:32 -07002573 StrBuf << "Alloca on non-i32 value. Found: " << *ByteCount;
Karl Schimpf742d72d2014-09-09 11:40:09 -07002574 Error(StrBuf.str());
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002575 appendErrorInstruction(PtrTy);
Karl Schimpf742d72d2014-09-09 11:40:09 -07002576 return;
2577 }
Jim Stichnoth8e928382015-02-02 17:03:08 -08002578 CurrentNode->appendInst(Ice::InstAlloca::create(
David Sehr2f3b8ec2015-11-16 16:51:39 -08002579 Func.get(), getNextInstVar(PtrTy), ByteCount, Alignment));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002580 return;
Karl Schimpf742d72d2014-09-09 11:40:09 -07002581 }
Karl Schimpf41689df2014-09-10 14:36:07 -07002582 case naclbitc::FUNC_CODE_INST_LOAD: {
2583 // LOAD: [address, align, ty]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002584 if (!isValidRecordSize(3, "load"))
Karl Schimpf41689df2014-09-10 14:36:07 -07002585 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002586 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex);
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002587 Ice::Type Ty = Context->getSimpleTypeByID(Values[2]);
Karl Schimpf07af2ac2015-09-30 15:33:41 -07002588 uint32_t Alignment = Context->extractAlignment(this, "Load", Values[1]);
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002589 if (!isValidPointerType(Address, "Load")) {
2590 appendErrorInstruction(Ty);
Karl Schimpf41689df2014-09-10 14:36:07 -07002591 return;
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002592 }
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002593 if (!isValidLoadStoreAlignment(Alignment, Ty, "Load")) {
2594 appendErrorInstruction(Ty);
Karl Schimpf41689df2014-09-10 14:36:07 -07002595 return;
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002596 }
Jim Stichnoth8e928382015-02-02 17:03:08 -08002597 CurrentNode->appendInst(Ice::InstLoad::create(
2598 Func.get(), getNextInstVar(Ty), Address, Alignment));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002599 return;
Karl Schimpf41689df2014-09-10 14:36:07 -07002600 }
2601 case naclbitc::FUNC_CODE_INST_STORE: {
2602 // STORE: [address, value, align]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002603 if (!isValidRecordSize(3, "store"))
Karl Schimpf41689df2014-09-10 14:36:07 -07002604 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002605 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex);
Karl Schimpf47661562014-09-11 14:42:49 -07002606 Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex);
Karl Schimpf07af2ac2015-09-30 15:33:41 -07002607 uint32_t Alignment = Context->extractAlignment(this, "Store", Values[2]);
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002608 if (!isValidPointerType(Address, "Store"))
2609 return;
Karl Schimpf41689df2014-09-10 14:36:07 -07002610 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store"))
2611 return;
Karl Schimpf47661562014-09-11 14:42:49 -07002612 CurrentNode->appendInst(
Jim Stichnoth8e928382015-02-02 17:03:08 -08002613 Ice::InstStore::create(Func.get(), Value, Address, Alignment));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002614 return;
Karl Schimpf41689df2014-09-10 14:36:07 -07002615 }
Karl Schimpf8df26f32014-09-19 09:33:26 -07002616 case naclbitc::FUNC_CODE_INST_CALL:
2617 case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: {
2618 // CALL: [cc, fnid, arg0, arg1...]
2619 // CALL_INDIRECT: [cc, fn, returnty, args...]
2620 //
Andrew Scull57e12682015-09-16 11:30:19 -07002621 // Note: The difference between CALL and CALL_INDIRECT is that CALL has a
2622 // reference to an explicit function declaration, while the CALL_INDIRECT
2623 // is just an address. For CALL, we can infer the return type by looking up
2624 // the type signature associated with the function declaration. For
2625 // CALL_INDIRECT we can only infer the type signature via argument types,
2626 // and the corresponding return type stored in CALL_INDIRECT record.
Karl Schimpf8df26f32014-09-19 09:33:26 -07002627 Ice::SizeT ParamsStartIndex = 2;
2628 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) {
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002629 if (!isValidRecordSizeAtLeast(2, "call"))
Karl Schimpf8df26f32014-09-19 09:33:26 -07002630 return;
2631 } else {
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002632 if (!isValidRecordSizeAtLeast(3, "call indirect"))
Karl Schimpf8df26f32014-09-19 09:33:26 -07002633 return;
2634 ParamsStartIndex = 3;
2635 }
2636
Karl Schimpf8df26f32014-09-19 09:33:26 -07002637 uint32_t CalleeIndex = convertRelativeToAbsIndex(Values[1], BaseIndex);
2638 Ice::Operand *Callee = getOperand(CalleeIndex);
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002639
2640 // Pull out signature/return type of call (if possible).
2641 Ice::FunctionDeclaration *Fcn = nullptr;
Karl Schimpfff94f592015-09-18 10:37:44 -07002642 const Ice::FuncSigType *Signature = nullptr;
Karl Schimpf8df26f32014-09-19 09:33:26 -07002643 Ice::Type ReturnType = Ice::IceType_void;
Karl Schimpfe3f64d02014-10-07 10:38:22 -07002644 const Ice::Intrinsics::FullIntrinsicInfo *IntrinsicInfo = nullptr;
Karl Schimpf8df26f32014-09-19 09:33:26 -07002645 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) {
Karl Schimpf958ff342015-09-22 14:09:06 -07002646 Fcn = Context->getFunctionByID(CalleeIndex);
Karl Schimpfff94f592015-09-18 10:37:44 -07002647 Signature = &Fcn->getSignature();
2648 ReturnType = Signature->getReturnType();
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002649 Ice::SizeT NumParams = Values.size() - ParamsStartIndex;
2650 if (NumParams != Signature->getNumArgs()) {
2651 std::string Buffer;
2652 raw_string_ostream StrBuf(Buffer);
2653 StrBuf << "Call to " << printName(Fcn) << " has " << NumParams
2654 << " parameters. Signature expects: " << Signature->getNumArgs();
2655 Error(StrBuf.str());
2656 if (ReturnType != Ice::IceType_void)
2657 setNextLocalInstIndex(nullptr);
2658 return;
2659 }
Karl Schimpf8df26f32014-09-19 09:33:26 -07002660
2661 // Check if this direct call is to an Intrinsic (starts with "llvm.")
Karl Schimpfbba77682016-01-15 07:33:15 -08002662 IntrinsicInfo = Fcn->getIntrinsicInfo(getTranslator().getContext());
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002663 if (IntrinsicInfo && IntrinsicInfo->getNumArgs() != NumParams) {
2664 std::string Buffer;
2665 raw_string_ostream StrBuf(Buffer);
2666 StrBuf << "Call to " << printName(Fcn) << " has " << NumParams
2667 << " parameters. Intrinsic expects: " << Signature->getNumArgs();
Jim Stichnotha67fc442015-03-03 16:13:11 -08002668 Error(StrBuf.str());
Karl Schimpfff94f592015-09-18 10:37:44 -07002669 if (ReturnType != Ice::IceType_void)
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002670 setNextLocalInstIndex(nullptr);
Jim Stichnotha67fc442015-03-03 16:13:11 -08002671 return;
Karl Schimpf8df26f32014-09-19 09:33:26 -07002672 }
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002673 } else { // Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL_INDIRECT
2674 // There is no signature. Assume defined by parameter types.
Karl Schimpf645aa1a2014-10-08 09:05:53 -07002675 ReturnType = Context->getSimpleTypeByID(Values[2]);
Jim Stichnoth0d4fc922015-12-13 21:36:33 -08002676 if (Callee != nullptr)
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002677 isValidPointerType(Callee, "Call indirect");
2678 }
2679
Jim Stichnoth0d4fc922015-12-13 21:36:33 -08002680 if (Callee == nullptr)
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002681 return;
2682
2683 // Extract out the the call parameters.
Jim Stichnoth48e3ae52015-10-01 13:33:35 -07002684 SmallVector<Ice::Operand *, 8> Params;
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002685 for (Ice::SizeT Index = ParamsStartIndex; Index < Values.size(); ++Index) {
2686 Ice::Operand *Op = getRelativeOperand(Values[Index], BaseIndex);
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002687 if (Op == nullptr) {
2688 std::string Buffer;
2689 raw_string_ostream StrBuf(Buffer);
Jim Stichnoth48e3ae52015-10-01 13:33:35 -07002690 StrBuf << "Parameter " << (Index - ParamsStartIndex + 1) << " of "
2691 << printName(Fcn) << " is not defined";
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002692 Error(StrBuf.str());
2693 if (ReturnType != Ice::IceType_void)
2694 setNextLocalInstIndex(nullptr);
2695 return;
2696 }
2697 Params.push_back(Op);
Karl Schimpf8df26f32014-09-19 09:33:26 -07002698 }
2699
Karl Schimpfff94f592015-09-18 10:37:44 -07002700 // Check return type.
2701 if (IntrinsicInfo == nullptr && !isCallReturnType(ReturnType)) {
2702 std::string Buffer;
2703 raw_string_ostream StrBuf(Buffer);
Jim Stichnoth48e3ae52015-10-01 13:33:35 -07002704 StrBuf << "Return type of " << printName(Fcn)
2705 << " is invalid: " << ReturnType;
Karl Schimpfff94f592015-09-18 10:37:44 -07002706 Error(StrBuf.str());
2707 ReturnType = Ice::IceType_i32;
2708 }
2709
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002710 // Type check call parameters.
2711 for (Ice::SizeT Index = 0; Index < Params.size(); ++Index) {
2712 Ice::Operand *Op = Params[Index];
2713 Ice::Type OpType = Op->getType();
2714 if (Signature)
Jim Stichnoth48e3ae52015-10-01 13:33:35 -07002715 verifyCallArgTypeMatches(Fcn, Index, OpType,
2716 Signature->getArgType(Index));
Karl Schimpfbba77682016-01-15 07:33:15 -08002717 else if (!isCallParameterType(OpType)) {
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002718 std::string Buffer;
2719 raw_string_ostream StrBuf(Buffer);
2720 StrBuf << "Argument " << *Op << " of " << printName(Fcn)
2721 << " has invalid type: " << Op->getType();
2722 Error(StrBuf.str());
2723 appendErrorInstruction(ReturnType);
Karl Schimpfbba77682016-01-15 07:33:15 -08002724 return;
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002725 }
2726 }
2727
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002728 // Extract call information.
2729 uint64_t CCInfo = Values[0];
2730 CallingConv::ID CallingConv;
2731 if (!naclbitc::DecodeCallingConv(CCInfo >> 1, CallingConv)) {
2732 std::string Buffer;
2733 raw_string_ostream StrBuf(Buffer);
2734 StrBuf << "Function call calling convention value " << (CCInfo >> 1)
2735 << " not understood.";
2736 Error(StrBuf.str());
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002737 appendErrorInstruction(ReturnType);
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002738 return;
2739 }
Jim Stichnoth2d6c8262016-02-07 09:50:27 -08002740 const bool IsTailCall = (CCInfo & 1);
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002741
Karl Schimpf8df26f32014-09-19 09:33:26 -07002742 // Create the call instruction.
Karl Schimpfe3f64d02014-10-07 10:38:22 -07002743 Ice::Variable *Dest = (ReturnType == Ice::IceType_void)
2744 ? nullptr
2745 : getNextInstVar(ReturnType);
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08002746 std::unique_ptr<Ice::InstCall> Instr;
Karl Schimpf8df26f32014-09-19 09:33:26 -07002747 if (IntrinsicInfo) {
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08002748 Instr.reset(Ice::InstIntrinsicCall::create(
2749 Func.get(), Params.size(), Dest, Callee, IntrinsicInfo->Info));
Karl Schimpf8df26f32014-09-19 09:33:26 -07002750 } else {
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08002751 Instr.reset(Ice::InstCall::create(Func.get(), Params.size(), Dest, Callee,
2752 IsTailCall));
Karl Schimpf8df26f32014-09-19 09:33:26 -07002753 }
Karl Schimpffc0a52d2015-09-28 11:22:55 -07002754 for (Ice::Operand *Param : Params)
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08002755 Instr->addArg(Param);
2756 CurrentNode->appendInst(Instr.release());
Karl Schimpf8df26f32014-09-19 09:33:26 -07002757 return;
2758 }
Karl Schimpf8f07aa82014-09-17 09:07:20 -07002759 case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF: {
2760 // FORWARDTYPEREF: [opval, ty]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002761 if (!isValidRecordSize(2, "forward type ref"))
Karl Schimpf8f07aa82014-09-17 09:07:20 -07002762 return;
Karl Schimpf6fcbddd2014-11-06 09:49:24 -08002763 Ice::Type OpType = Context->getSimpleTypeByID(Values[1]);
Jim Stichnoth0d4fc922015-12-13 21:36:33 -08002764 setOperand(Values[0], createInstVar(OpType));
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002765 return;
Karl Schimpf8f07aa82014-09-17 09:07:20 -07002766 }
Karl Schimpfd6064a12014-08-27 15:34:58 -07002767 default:
2768 // Generate error message!
2769 BlockParserBaseClass::ProcessRecord();
Karl Schimpfaff9fa22014-10-29 14:32:07 -07002770 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -07002771 }
Karl Schimpfd6064a12014-08-27 15:34:58 -07002772}
2773
Karl Schimpff12355e2014-09-08 13:41:09 -07002774/// Parses constants within a function block.
2775class ConstantsParser : public BlockParserBaseClass {
Jim Stichnothc6ead202015-02-24 09:30:30 -08002776 ConstantsParser() = delete;
Jim Stichnoth0795ba02014-10-01 14:23:01 -07002777 ConstantsParser(const ConstantsParser &) = delete;
2778 ConstantsParser &operator=(const ConstantsParser &) = delete;
Karl Schimpff12355e2014-09-08 13:41:09 -07002779
2780public:
2781 ConstantsParser(unsigned BlockID, FunctionParser *FuncParser)
Karl Schimpf58455872014-11-03 11:29:39 -08002782 : BlockParserBaseClass(BlockID, FuncParser),
2783 Timer(Ice::TimerStack::TT_parseConstants, getTranslator().getContext()),
Jim Stichnotheafb56c2015-06-22 10:35:22 -07002784 FuncParser(FuncParser) {}
Karl Schimpff12355e2014-09-08 13:41:09 -07002785
Jim Stichnothe587d942015-06-22 15:49:04 -07002786 ~ConstantsParser() override = default;
Karl Schimpff12355e2014-09-08 13:41:09 -07002787
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002788 const char *getBlockName() const override { return "constants"; }
2789
Karl Schimpff12355e2014-09-08 13:41:09 -07002790private:
Karl Schimpf58455872014-11-03 11:29:39 -08002791 Ice::TimerMarker Timer;
Karl Schimpff12355e2014-09-08 13:41:09 -07002792 // The parser of the function block this constants block appears in.
2793 FunctionParser *FuncParser;
2794 // The type to use for succeeding constants.
Jim Stichnotheafb56c2015-06-22 10:35:22 -07002795 Ice::Type NextConstantType = Ice::IceType_void;
Karl Schimpff12355e2014-09-08 13:41:09 -07002796
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07002797 void ProcessRecord() override;
Karl Schimpff12355e2014-09-08 13:41:09 -07002798
2799 Ice::GlobalContext *getContext() { return getTranslator().getContext(); }
2800
Andrew Scull57e12682015-09-16 11:30:19 -07002801 // Returns true if the type to use for succeeding constants is defined. If
2802 // false, also generates an error message.
Karl Schimpff12355e2014-09-08 13:41:09 -07002803 bool isValidNextConstantType() {
2804 if (NextConstantType != Ice::IceType_void)
2805 return true;
2806 Error("Constant record not preceded by set type record");
2807 return false;
2808 }
2809};
2810
2811void ConstantsParser::ProcessRecord() {
2812 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
2813 switch (Record.GetCode()) {
2814 case naclbitc::CST_CODE_SETTYPE: {
2815 // SETTYPE: [typeid]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002816 if (!isValidRecordSize(1, "set type"))
Karl Schimpff12355e2014-09-08 13:41:09 -07002817 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -07002818 NextConstantType = Context->getSimpleTypeByID(Values[0]);
Karl Schimpff12355e2014-09-08 13:41:09 -07002819 if (NextConstantType == Ice::IceType_void)
2820 Error("constants block set type not allowed for void type");
2821 return;
2822 }
2823 case naclbitc::CST_CODE_UNDEF: {
2824 // UNDEF
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002825 if (!isValidRecordSize(0, "undef"))
Karl Schimpff12355e2014-09-08 13:41:09 -07002826 return;
2827 if (!isValidNextConstantType())
2828 return;
2829 FuncParser->setNextConstantID(
2830 getContext()->getConstantUndef(NextConstantType));
2831 return;
2832 }
2833 case naclbitc::CST_CODE_INTEGER: {
2834 // INTEGER: [intval]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002835 if (!isValidRecordSize(1, "integer"))
Karl Schimpff12355e2014-09-08 13:41:09 -07002836 return;
2837 if (!isValidNextConstantType())
2838 return;
Karl Schimpf4019f082014-12-15 13:45:00 -08002839 if (Ice::isScalarIntegerType(NextConstantType)) {
Karl Schimpfa5295b02015-12-01 11:24:53 -08002840 BitcodeInt Value(Ice::getScalarIntBitWidth(NextConstantType),
Karl Schimpf32817482014-12-15 09:52:26 -08002841 NaClDecodeSignRotatedValue(Values[0]));
Jim Stichnothd2cb4362014-11-20 11:24:42 -08002842 if (Ice::Constant *C = getContext()->getConstantInt(
2843 NextConstantType, Value.getSExtValue())) {
2844 FuncParser->setNextConstantID(C);
2845 return;
2846 }
Karl Schimpff12355e2014-09-08 13:41:09 -07002847 }
2848 std::string Buffer;
2849 raw_string_ostream StrBuf(Buffer);
2850 StrBuf << "constant block integer record for non-integer type "
2851 << NextConstantType;
2852 Error(StrBuf.str());
2853 return;
2854 }
2855 case naclbitc::CST_CODE_FLOAT: {
2856 // FLOAT: [fpval]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002857 if (!isValidRecordSize(1, "float"))
Karl Schimpff12355e2014-09-08 13:41:09 -07002858 return;
2859 if (!isValidNextConstantType())
2860 return;
2861 switch (NextConstantType) {
2862 case Ice::IceType_f32: {
Karl Schimpfa5295b02015-12-01 11:24:53 -08002863 const BitcodeInt Value(32, static_cast<uint32_t>(Values[0]));
2864 float FpValue = Value.convertToFp<int32_t, float>();
Karl Schimpf32817482014-12-15 09:52:26 -08002865 FuncParser->setNextConstantID(getContext()->getConstantFloat(FpValue));
Karl Schimpff12355e2014-09-08 13:41:09 -07002866 return;
2867 }
2868 case Ice::IceType_f64: {
Karl Schimpfa5295b02015-12-01 11:24:53 -08002869 const BitcodeInt Value(64, Values[0]);
2870 double FpValue = Value.convertToFp<uint64_t, double>();
Karl Schimpf32817482014-12-15 09:52:26 -08002871 FuncParser->setNextConstantID(getContext()->getConstantDouble(FpValue));
Karl Schimpff12355e2014-09-08 13:41:09 -07002872 return;
2873 }
2874 default: {
2875 std::string Buffer;
2876 raw_string_ostream StrBuf(Buffer);
2877 StrBuf << "constant block float record for non-floating type "
2878 << NextConstantType;
2879 Error(StrBuf.str());
2880 return;
2881 }
2882 }
2883 }
2884 default:
2885 // Generate error message!
2886 BlockParserBaseClass::ProcessRecord();
2887 return;
2888 }
2889}
2890
Karl Schimpfc132b762014-09-11 09:43:47 -07002891// Parses valuesymtab blocks appearing in a function block.
2892class FunctionValuesymtabParser : public ValuesymtabParser {
Jim Stichnothc6ead202015-02-24 09:30:30 -08002893 FunctionValuesymtabParser() = delete;
Jim Stichnoth0795ba02014-10-01 14:23:01 -07002894 FunctionValuesymtabParser(const FunctionValuesymtabParser &) = delete;
2895 void operator=(const FunctionValuesymtabParser &) = delete;
Karl Schimpfc132b762014-09-11 09:43:47 -07002896
2897public:
2898 FunctionValuesymtabParser(unsigned BlockID, FunctionParser *EnclosingParser)
Karl Schimpf58455872014-11-03 11:29:39 -08002899 : ValuesymtabParser(BlockID, EnclosingParser),
2900 Timer(Ice::TimerStack::TT_parseFunctionValuesymtabs,
2901 getTranslator().getContext()) {}
Karl Schimpfc132b762014-09-11 09:43:47 -07002902
2903private:
Karl Schimpf58455872014-11-03 11:29:39 -08002904 Ice::TimerMarker Timer;
Karl Schimpfc132b762014-09-11 09:43:47 -07002905 // Returns the enclosing function parser.
2906 FunctionParser *getFunctionParser() const {
2907 return reinterpret_cast<FunctionParser *>(GetEnclosingParser());
2908 }
2909
Karl Schimpf52863b12015-09-16 13:51:21 -07002910 const char *getTableKind() const final { return "Function"; }
2911
2912 void setValueName(NaClBcIndexSize_t Index, StringType &Name) final;
2913 void setBbName(NaClBcIndexSize_t Index, StringType &Name) final;
Karl Schimpfc132b762014-09-11 09:43:47 -07002914
Andrew Scull57e12682015-09-16 11:30:19 -07002915 // Reports that the assignment of Name to the value associated with index is
2916 // not possible, for the given Context.
Karl Schimpf74cd8832015-06-23 11:05:01 -07002917 void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index,
Karl Schimpfc132b762014-09-11 09:43:47 -07002918 StringType &Name) {
2919 std::string Buffer;
2920 raw_string_ostream StrBuf(Buffer);
2921 StrBuf << "Function-local " << Context << " name '" << Name
2922 << "' can't be associated with index " << Index;
2923 Error(StrBuf.str());
2924 }
2925};
2926
Karl Schimpf74cd8832015-06-23 11:05:01 -07002927void FunctionValuesymtabParser::setValueName(NaClBcIndexSize_t Index,
2928 StringType &Name) {
Karl Schimpfc132b762014-09-11 09:43:47 -07002929 // Note: We check when Index is too small, so that we can error recover
2930 // (FP->getOperand will create fatal error).
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002931 if (Index < getFunctionParser()->getNumGlobalIDs()) {
Karl Schimpf52863b12015-09-16 13:51:21 -07002932 reportUnableToAssign("Global value", Index, Name);
Karl Schimpfc132b762014-09-11 09:43:47 -07002933 return;
2934 }
2935 Ice::Operand *Op = getFunctionParser()->getOperand(Index);
Jim Stichnoth54f3d512015-12-11 09:53:00 -08002936 if (auto *V = dyn_cast<Ice::Variable>(Op)) {
Jim Stichnoth20b71f52015-06-24 15:52:24 -07002937 if (Ice::BuildDefs::dump()) {
Jim Stichnoth9a04c072014-12-11 15:51:42 -08002938 std::string Nm(Name.data(), Name.size());
2939 V->setName(getFunctionParser()->getFunc(), Nm);
2940 }
Karl Schimpfc132b762014-09-11 09:43:47 -07002941 } else {
Karl Schimpf52863b12015-09-16 13:51:21 -07002942 reportUnableToAssign("Local value", Index, Name);
Karl Schimpfc132b762014-09-11 09:43:47 -07002943 }
2944}
2945
Karl Schimpf74cd8832015-06-23 11:05:01 -07002946void FunctionValuesymtabParser::setBbName(NaClBcIndexSize_t Index,
2947 StringType &Name) {
Karl Schimpfac7d7342015-08-06 12:55:23 -07002948 if (!Ice::BuildDefs::dump())
2949 return;
Karl Schimpf98ed4462015-08-14 13:08:42 -07002950 if (Index >= getFunctionParser()->getFunc()->getNumNodes()) {
Karl Schimpf52863b12015-09-16 13:51:21 -07002951 reportUnableToAssign("Basic block", Index, Name);
Karl Schimpf98ed4462015-08-14 13:08:42 -07002952 return;
2953 }
Karl Schimpfc132b762014-09-11 09:43:47 -07002954 std::string Nm(Name.data(), Name.size());
Karl Schimpf98ed4462015-08-14 13:08:42 -07002955 if (Ice::BuildDefs::dump())
2956 getFunctionParser()->getFunc()->getNodes()[Index]->setName(Nm);
Karl Schimpfc132b762014-09-11 09:43:47 -07002957}
2958
Karl Schimpff12355e2014-09-08 13:41:09 -07002959bool FunctionParser::ParseBlock(unsigned BlockID) {
2960 switch (BlockID) {
2961 case naclbitc::CONSTANTS_BLOCK_ID: {
2962 ConstantsParser Parser(BlockID, this);
2963 return Parser.ParseThisBlock();
2964 }
Karl Schimpfc132b762014-09-11 09:43:47 -07002965 case naclbitc::VALUE_SYMTAB_BLOCK_ID: {
2966 if (PNaClAllowLocalSymbolTables) {
2967 FunctionValuesymtabParser Parser(BlockID, this);
2968 return Parser.ParseThisBlock();
2969 }
2970 break;
Karl Schimpff12355e2014-09-08 13:41:09 -07002971 }
Karl Schimpfc132b762014-09-11 09:43:47 -07002972 default:
2973 break;
2974 }
2975 return BlockParserBaseClass::ParseBlock(BlockID);
Karl Schimpff12355e2014-09-08 13:41:09 -07002976}
2977
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002978/// Parses the module block in the bitcode file.
2979class ModuleParser : public BlockParserBaseClass {
Jim Stichnothc6ead202015-02-24 09:30:30 -08002980 ModuleParser() = delete;
2981 ModuleParser(const ModuleParser &) = delete;
2982 ModuleParser &operator=(const ModuleParser &) = delete;
2983
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002984public:
2985 ModuleParser(unsigned BlockID, TopLevelParser *Context)
Karl Schimpf6ff33d22014-09-22 10:28:42 -07002986 : BlockParserBaseClass(BlockID, Context),
Karl Schimpf58455872014-11-03 11:29:39 -08002987 Timer(Ice::TimerStack::TT_parseModule,
Jim Stichnotheafb56c2015-06-22 10:35:22 -07002988 Context->getTranslator().getContext()) {}
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002989
Jim Stichnothe587d942015-06-22 15:49:04 -07002990 ~ModuleParser() override = default;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002991
Karl Schimpf2f6f8602014-12-01 13:39:00 -08002992 const char *getBlockName() const override { return "module"; }
2993
Karl Schimpf5ee234a2014-09-12 10:41:40 -07002994private:
Karl Schimpf58455872014-11-03 11:29:39 -08002995 Ice::TimerMarker Timer;
Karl Schimpf9d98d792014-10-13 15:01:08 -07002996 // True if we have already installed names for unnamed global declarations,
2997 // and have generated global constant initializers.
Jim Stichnotheafb56c2015-06-22 10:35:22 -07002998 bool GlobalDeclarationNamesAndInitializersInstalled = false;
Karl Schimpfc49eeae2015-09-17 10:19:48 -07002999 // True if we have already processed the symbol table for the module.
3000 bool FoundValuesymtab = false;
Karl Schimpf6ff33d22014-09-22 10:28:42 -07003001
Andrew Scull57e12682015-09-16 11:30:19 -07003002 // Generates names for unnamed global addresses (i.e. functions and global
3003 // variables). Then lowers global variable declaration initializers to the
3004 // target. May be called multiple times. Only the first call will do the
3005 // installation.
Karl Schimpf74cd8832015-06-23 11:05:01 -07003006 void installGlobalNamesAndGlobalVarInitializers() {
Karl Schimpf9d98d792014-10-13 15:01:08 -07003007 if (!GlobalDeclarationNamesAndInitializersInstalled) {
Karl Schimpf6ca7d2b2015-02-10 14:43:45 -08003008 Context->installGlobalNames();
3009 Context->createValueIDs();
Karl Schimpfbba77682016-01-15 07:33:15 -08003010 Context->verifyFunctionTypeSignatures();
Karl Schimpfc49eeae2015-09-17 10:19:48 -07003011 std::unique_ptr<Ice::VariableDeclarationList> Globals =
3012 Context->getGlobalVariables();
3013 if (Globals)
3014 getTranslator().lowerGlobals(std::move(Globals));
Karl Schimpf9d98d792014-10-13 15:01:08 -07003015 GlobalDeclarationNamesAndInitializersInstalled = true;
3016 }
3017 }
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07003018 bool ParseBlock(unsigned BlockID) override;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003019
Karl Schimpf74cd8832015-06-23 11:05:01 -07003020 void ExitBlock() override { installGlobalNamesAndGlobalVarInitializers(); }
Karl Schimpf6ff33d22014-09-22 10:28:42 -07003021
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07003022 void ProcessRecord() override;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003023};
3024
Karl Schimpfc132b762014-09-11 09:43:47 -07003025class ModuleValuesymtabParser : public ValuesymtabParser {
Jim Stichnothc6ead202015-02-24 09:30:30 -08003026 ModuleValuesymtabParser() = delete;
Jim Stichnoth0795ba02014-10-01 14:23:01 -07003027 ModuleValuesymtabParser(const ModuleValuesymtabParser &) = delete;
3028 void operator=(const ModuleValuesymtabParser &) = delete;
Karl Schimpfc132b762014-09-11 09:43:47 -07003029
3030public:
3031 ModuleValuesymtabParser(unsigned BlockID, ModuleParser *MP)
Karl Schimpf58455872014-11-03 11:29:39 -08003032 : ValuesymtabParser(BlockID, MP),
3033 Timer(Ice::TimerStack::TT_parseModuleValuesymtabs,
3034 getTranslator().getContext()) {}
Karl Schimpfc132b762014-09-11 09:43:47 -07003035
Jim Stichnothe587d942015-06-22 15:49:04 -07003036 ~ModuleValuesymtabParser() override = default;
Karl Schimpfc132b762014-09-11 09:43:47 -07003037
3038private:
Karl Schimpf58455872014-11-03 11:29:39 -08003039 Ice::TimerMarker Timer;
Karl Schimpf52863b12015-09-16 13:51:21 -07003040 const char *getTableKind() const final { return "Module"; }
3041 void setValueName(NaClBcIndexSize_t Index, StringType &Name) final;
3042 void setBbName(NaClBcIndexSize_t Index, StringType &Name) final;
Karl Schimpfc132b762014-09-11 09:43:47 -07003043};
3044
Karl Schimpf74cd8832015-06-23 11:05:01 -07003045void ModuleValuesymtabParser::setValueName(NaClBcIndexSize_t Index,
3046 StringType &Name) {
Karl Schimpf9d98d792014-10-13 15:01:08 -07003047 Context->getGlobalDeclarationByID(Index)
3048 ->setName(StringRef(Name.data(), Name.size()));
Karl Schimpfc132b762014-09-11 09:43:47 -07003049}
3050
Karl Schimpf74cd8832015-06-23 11:05:01 -07003051void ModuleValuesymtabParser::setBbName(NaClBcIndexSize_t Index,
3052 StringType &Name) {
Karl Schimpf52863b12015-09-16 13:51:21 -07003053 reportUnableToAssign("Basic block", Index, Name);
Karl Schimpfc132b762014-09-11 09:43:47 -07003054}
3055
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07003056bool ModuleParser::ParseBlock(unsigned BlockID) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003057 switch (BlockID) {
3058 case naclbitc::BLOCKINFO_BLOCK_ID:
3059 return NaClBitcodeParser::ParseBlock(BlockID);
3060 case naclbitc::TYPE_BLOCK_ID_NEW: {
3061 TypesParser Parser(BlockID, this);
3062 return Parser.ParseThisBlock();
3063 }
3064 case naclbitc::GLOBALVAR_BLOCK_ID: {
3065 GlobalsParser Parser(BlockID, this);
3066 return Parser.ParseThisBlock();
3067 }
3068 case naclbitc::VALUE_SYMTAB_BLOCK_ID: {
Karl Schimpfc49eeae2015-09-17 10:19:48 -07003069 if (FoundValuesymtab)
3070 Fatal("Duplicate valuesymtab in module");
3071
Karl Schimpf28fc2d72015-09-22 13:14:55 -07003072 // If we have already processed a function block (i.e. we have already
3073 // installed global names and variable initializers) we can no longer accept
3074 // the value symbol table. Names have already been generated.
3075 if (GlobalDeclarationNamesAndInitializersInstalled)
3076 Fatal("Module valuesymtab not allowed after function blocks");
3077
Karl Schimpfc49eeae2015-09-17 10:19:48 -07003078 FoundValuesymtab = true;
Karl Schimpfc132b762014-09-11 09:43:47 -07003079 ModuleValuesymtabParser Parser(BlockID, this);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003080 return Parser.ParseThisBlock();
3081 }
3082 case naclbitc::FUNCTION_BLOCK_ID: {
Karl Schimpf74cd8832015-06-23 11:05:01 -07003083 installGlobalNamesAndGlobalVarInitializers();
Karl Schimpfd6064a12014-08-27 15:34:58 -07003084 FunctionParser Parser(BlockID, this);
Jim Stichnoth8e928382015-02-02 17:03:08 -08003085 return Parser.convertFunction();
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003086 }
3087 default:
3088 return BlockParserBaseClass::ParseBlock(BlockID);
3089 }
3090}
3091
3092void ModuleParser::ProcessRecord() {
3093 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
3094 switch (Record.GetCode()) {
3095 case naclbitc::MODULE_CODE_VERSION: {
3096 // VERSION: [version#]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08003097 if (!isValidRecordSize(1, "version"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003098 return;
Karl Schimpf74cd8832015-06-23 11:05:01 -07003099 uint64_t Version = Values[0];
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003100 if (Version != 1) {
3101 std::string Buffer;
3102 raw_string_ostream StrBuf(Buffer);
3103 StrBuf << "Unknown bitstream version: " << Version;
3104 Error(StrBuf.str());
3105 }
3106 return;
3107 }
3108 case naclbitc::MODULE_CODE_FUNCTION: {
3109 // FUNCTION: [type, callingconv, isproto, linkage]
Karl Schimpf2f6f8602014-12-01 13:39:00 -08003110 if (!isValidRecordSize(4, "address"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003111 return;
Karl Schimpf9d98d792014-10-13 15:01:08 -07003112 const Ice::FuncSigType &Signature = Context->getFuncSigTypeByID(Values[0]);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003113 CallingConv::ID CallingConv;
3114 if (!naclbitc::DecodeCallingConv(Values[1], CallingConv)) {
3115 std::string Buffer;
3116 raw_string_ostream StrBuf(Buffer);
Karl Schimpf2f6f8602014-12-01 13:39:00 -08003117 StrBuf << "Function address has unknown calling convention: "
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003118 << Values[1];
3119 Error(StrBuf.str());
3120 return;
3121 }
3122 GlobalValue::LinkageTypes Linkage;
3123 if (!naclbitc::DecodeLinkage(Values[3], Linkage)) {
3124 std::string Buffer;
3125 raw_string_ostream StrBuf(Buffer);
Karl Schimpf2f6f8602014-12-01 13:39:00 -08003126 StrBuf << "Function address has unknown linkage. Found " << Values[3];
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003127 Error(StrBuf.str());
3128 return;
3129 }
Karl Schimpf0c729c82015-01-28 10:58:25 -08003130 bool IsProto = Values[2] == 1;
Jim Stichnoth54f3d512015-12-11 09:53:00 -08003131 auto *Func = Ice::FunctionDeclaration::create(
John Porto1bec8bc2015-06-22 10:51:13 -07003132 Context->getTranslator().getContext(), Signature, CallingConv, Linkage,
3133 IsProto);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003134 Context->setNextFunctionID(Func);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003135 return;
3136 }
3137 default:
3138 BlockParserBaseClass::ProcessRecord();
3139 return;
3140 }
3141}
3142
3143bool TopLevelParser::ParseBlock(unsigned BlockID) {
3144 if (BlockID == naclbitc::MODULE_BLOCK_ID) {
Karl Schimpf0b8763e2015-09-22 10:41:11 -07003145 if (ParsedModuleBlock)
3146 Fatal("Input can't contain more than one module");
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003147 ModuleParser Parser(BlockID, this);
Karl Schimpf0b8763e2015-09-22 10:41:11 -07003148 bool ParseFailed = Parser.ParseThisBlock();
3149 ParsedModuleBlock = true;
3150 return ParseFailed;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003151 }
3152 // Generate error message by using default block implementation.
3153 BlockParserBaseClass Parser(BlockID, this);
3154 return Parser.ParseThisBlock();
3155}
3156
Jim Stichnoth989a7032014-08-08 10:13:44 -07003157} // end of anonymous namespace
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003158
3159namespace Ice {
3160
Karl Schimpf2e7daef2015-01-09 13:04:13 -08003161void PNaClTranslator::translateBuffer(const std::string &IRFilename,
3162 MemoryBuffer *MemBuf) {
Jan Voungc1f07ea2015-03-06 14:53:30 -08003163 std::unique_ptr<MemoryObject> MemObj(getNonStreamedMemoryObject(
3164 reinterpret_cast<const unsigned char *>(MemBuf->getBufferStart()),
3165 reinterpret_cast<const unsigned char *>(MemBuf->getBufferEnd())));
3166 translate(IRFilename, std::move(MemObj));
3167}
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003168
Jan Voungc1f07ea2015-03-06 14:53:30 -08003169void PNaClTranslator::translate(const std::string &IRFilename,
3170 std::unique_ptr<MemoryObject> &&MemObj) {
Andrew Scull57e12682015-09-16 11:30:19 -07003171 // On error, we report_fatal_error to avoid destroying the MemObj. That may
3172 // still be in use by IceBrowserCompileServer. Otherwise, we need to change
3173 // the MemObj to be ref-counted, or have a wrapper, or simply leak. We also
3174 // need a hook to tell the IceBrowserCompileServer to unblock its
3175 // QueueStreamer.
Jan Voung2f7f2b72015-06-03 17:50:20 -07003176 // https://code.google.com/p/nativeclient/issues/detail?id=4163
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003177 // Read header and verify it is good.
3178 NaClBitcodeHeader Header;
Karl Schimpfb33a2af2015-05-12 08:26:23 -07003179 if (Header.Read(MemObj.get())) {
Jan Voung2f7f2b72015-06-03 17:50:20 -07003180 llvm::report_fatal_error("Invalid PNaCl bitcode header");
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003181 }
Karl Schimpfb33a2af2015-05-12 08:26:23 -07003182 if (!Header.IsSupported()) {
Karl Schimpf0b8763e2015-09-22 10:41:11 -07003183 getContext()->getStrError() << Header.Unsupported();
Karl Schimpfb33a2af2015-05-12 08:26:23 -07003184 if (!Header.IsReadable()) {
Jan Voung2f7f2b72015-06-03 17:50:20 -07003185 llvm::report_fatal_error("Invalid PNaCl bitcode header");
Karl Schimpfb33a2af2015-05-12 08:26:23 -07003186 }
3187 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003188
3189 // Create a bitstream reader to read the bitcode file.
Karl Schimpfb33a2af2015-05-12 08:26:23 -07003190 NaClBitstreamReader InputStreamFile(MemObj.release(), Header);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003191 NaClBitstreamCursor InputStream(InputStreamFile);
3192
Karl Schimpf22ed4eb2015-03-04 12:17:20 -08003193 TopLevelParser Parser(*this, InputStream, ErrorStatus);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003194 while (!InputStream.AtEndOfStream()) {
3195 if (Parser.Parse()) {
Jim Stichnothfa4efea2015-01-27 05:06:03 -08003196 ErrorStatus.assign(EC_Bitcode);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003197 return;
3198 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003199 }
3200
Karl Schimpf0b8763e2015-09-22 10:41:11 -07003201 if (!Parser.parsedModuleBlock()) {
3202 std::string Buffer;
3203 raw_string_ostream StrBuf(Buffer);
3204 StrBuf << IRFilename << ": Does not contain a module!";
3205 llvm::report_fatal_error(StrBuf.str());
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003206 }
Jan Voungc1f07ea2015-03-06 14:53:30 -08003207 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) {
Jan Voung2f7f2b72015-06-03 17:50:20 -07003208 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes");
Jan Voungc1f07ea2015-03-06 14:53:30 -08003209 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -07003210}
3211
Jim Stichnoth989a7032014-08-08 10:13:44 -07003212} // end of namespace Ice