OLD | NEW |
---|---|
1 //===- subzero/src/PNaClTranslator.cpp - ICE from bitcode -----------------===// | 1 //===- subzero/src/PNaClTranslator.cpp - ICE from bitcode -----------------===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 /// | 9 /// |
10 /// \file | 10 /// \file |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
345 /// ownership of the current list of global variables. Note: only returns | 345 /// ownership of the current list of global variables. Note: only returns |
346 /// non-null pointer on first call. All successive calls return a null | 346 /// non-null pointer on first call. All successive calls return a null |
347 /// pointer. | 347 /// pointer. |
348 std::unique_ptr<Ice::VariableDeclarationList> getGlobalVariables() { | 348 std::unique_ptr<Ice::VariableDeclarationList> getGlobalVariables() { |
349 // Before returning, check that ValidIDConstants has already been built. | 349 // Before returning, check that ValidIDConstants has already been built. |
350 assert(!VariableDeclarations || | 350 assert(!VariableDeclarations || |
351 VariableDeclarations->size() <= ValueIDConstants.size()); | 351 VariableDeclarations->size() <= ValueIDConstants.size()); |
352 return std::move(VariableDeclarations); | 352 return std::move(VariableDeclarations); |
353 } | 353 } |
354 | 354 |
355 // Upper limit of alignment power allowed by LLVM | |
356 static const uint32_t AlignPowerLimit = 29; | |
Jim Stichnoth
2015/09/30 21:40:21
constexpr ?
Karl
2015/09/30 22:23:45
Done.
| |
357 | |
358 // Extracts the corresponding Alignment to use, given the AlignPower (i.e. | |
359 // 2**(AlignPower-1), or 0 if AlignPower == 0). Parser defines the block | |
360 // context the alignment check appears in, and Prefix defines the context the | |
361 // alignment appears in. | |
362 void extractAlignment(NaClBitcodeParser *Parser, const char *Prefix, | |
Jim Stichnoth
2015/09/30 21:40:21
Can this function directly return Alignment instea
Karl
2015/09/30 22:23:45
Done.
| |
363 uint32_t AlignPower, uint32_t &Alignment) { | |
364 if (AlignPower <= AlignPowerLimit + 1) { | |
365 Alignment = (1 << AlignPower) >> 1; | |
366 return; | |
367 } | |
368 std::string Buffer; | |
369 raw_string_ostream StrBuf(Buffer); | |
370 StrBuf << Prefix << " alignment greater than 2**" << AlignPowerLimit | |
371 << ". Found: 2**" << (AlignPower - 1); | |
372 Parser->Error(StrBuf.str()); | |
373 // Error recover with value that is always acceptable. | |
374 Alignment = 1; | |
375 } | |
376 | |
355 private: | 377 private: |
356 // The translator associated with the parser. | 378 // The translator associated with the parser. |
357 Ice::Translator &Translator; | 379 Ice::Translator &Translator; |
358 // The exit status that should be set to true if an error occurs. | 380 // The exit status that should be set to true if an error occurs. |
359 Ice::ErrorCode &ErrorStatus; | 381 Ice::ErrorCode &ErrorStatus; |
360 // The number of errors reported. | 382 // The number of errors reported. |
361 unsigned NumErrors = 0; | 383 unsigned NumErrors = 0; |
362 // The types associated with each type ID. | 384 // The types associated with each type ID. |
363 std::vector<ExtendedType> TypeIDValues; | 385 std::vector<ExtendedType> TypeIDValues; |
364 // The set of functions (prototype and defined). | 386 // The set of functions (prototype and defined). |
(...skipping 689 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1054 SpecifiedNumberVars = Values[0]; | 1076 SpecifiedNumberVars = Values[0]; |
1055 return; | 1077 return; |
1056 case naclbitc::GLOBALVAR_VAR: { | 1078 case naclbitc::GLOBALVAR_VAR: { |
1057 // VAR: [align, isconst] | 1079 // VAR: [align, isconst] |
1058 if (!isValidRecordSize(2, "variable")) | 1080 if (!isValidRecordSize(2, "variable")) |
1059 return; | 1081 return; |
1060 verifyNoMissingInitializers(); | 1082 verifyNoMissingInitializers(); |
1061 // Always build the global variable, even if IR generation is turned off. | 1083 // Always build the global variable, even if IR generation is turned off. |
1062 // This is needed because we need a placeholder in the top-level context | 1084 // This is needed because we need a placeholder in the top-level context |
1063 // when no IR is generated. | 1085 // when no IR is generated. |
1086 uint32_t Alignment; | |
1087 Context->extractAlignment(this, "Global variable", Values[0], Alignment); | |
1064 CurGlobalVar = getGlobalVarByID(NextGlobalID); | 1088 CurGlobalVar = getGlobalVarByID(NextGlobalID); |
1065 if (!isIRGenerationDisabled()) { | 1089 if (!isIRGenerationDisabled()) { |
1066 InitializersNeeded = 1; | 1090 InitializersNeeded = 1; |
1067 CurGlobalVar->setAlignment((1 << Values[0]) >> 1); | 1091 CurGlobalVar->setAlignment(Alignment); |
1068 CurGlobalVar->setIsConstant(Values[1] != 0); | 1092 CurGlobalVar->setIsConstant(Values[1] != 0); |
1069 } | 1093 } |
1070 ++NextGlobalID; | 1094 ++NextGlobalID; |
1071 return; | 1095 return; |
1072 } | 1096 } |
1073 case naclbitc::GLOBALVAR_COMPOUND: | 1097 case naclbitc::GLOBALVAR_COMPOUND: |
1074 // COMPOUND: [size] | 1098 // COMPOUND: [size] |
1075 if (!isValidRecordSize(1, "compound")) | 1099 if (!isValidRecordSize(1, "compound")) |
1076 return; | 1100 return; |
1077 if (!CurGlobalVar->getInitializers().empty()) { | 1101 if (!CurGlobalVar->getInitializers().empty()) { |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1374 // Holds the dividing point between local and global absolute value indices. | 1398 // Holds the dividing point between local and global absolute value indices. |
1375 size_t CachedNumGlobalValueIDs; | 1399 size_t CachedNumGlobalValueIDs; |
1376 // Holds operands local to the function block, based on indices defined in | 1400 // Holds operands local to the function block, based on indices defined in |
1377 // the bitcode file. | 1401 // the bitcode file. |
1378 Ice::OperandList LocalOperands; | 1402 Ice::OperandList LocalOperands; |
1379 // Holds the index within LocalOperands corresponding to the next instruction | 1403 // Holds the index within LocalOperands corresponding to the next instruction |
1380 // that generates a value. | 1404 // that generates a value. |
1381 NaClBcIndexSize_t NextLocalInstIndex; | 1405 NaClBcIndexSize_t NextLocalInstIndex; |
1382 // True if the last processed instruction was a terminating instruction. | 1406 // True if the last processed instruction was a terminating instruction. |
1383 bool InstIsTerminating = false; | 1407 bool InstIsTerminating = false; |
1384 // Upper limit of alignment power allowed by LLVM | |
1385 static const uint32_t AlignPowerLimit = 29; | |
1386 | |
1387 // Extracts the corresponding Alignment to use, given the AlignPower (i.e. | |
1388 // 2**(AlignPower-1), or 0 if AlignPower == 0). InstName is the name of the | |
1389 // instruction the alignment appears in. | |
1390 void extractAlignment(const char *InstName, uint32_t AlignPower, | |
1391 uint32_t &Alignment) { | |
1392 if (AlignPower <= AlignPowerLimit + 1) { | |
1393 Alignment = (1 << AlignPower) >> 1; | |
1394 return; | |
1395 } | |
1396 std::string Buffer; | |
1397 raw_string_ostream StrBuf(Buffer); | |
1398 StrBuf << InstName << " alignment greater than 2**" << AlignPowerLimit | |
1399 << ". Found: 2**" << (AlignPower - 1); | |
1400 Error(StrBuf.str()); | |
1401 // Error recover with value that is always acceptable. | |
1402 Alignment = 1; | |
1403 } | |
1404 | 1408 |
1405 bool ParseBlock(unsigned BlockID) override; | 1409 bool ParseBlock(unsigned BlockID) override; |
1406 | 1410 |
1407 void ProcessRecord() override; | 1411 void ProcessRecord() override; |
1408 | 1412 |
1409 void EnterBlock(unsigned NumWords) final { | 1413 void EnterBlock(unsigned NumWords) final { |
1410 // Note: Bitstream defines words as 32-bit values. | 1414 // Note: Bitstream defines words as 32-bit values. |
1411 NumBytesDefiningFunction = NumWords * sizeof(uint32_t); | 1415 NumBytesDefiningFunction = NumWords * sizeof(uint32_t); |
1412 // We know that all records are minimally defined by a two-bit abreviation. | 1416 // We know that all records are minimally defined by a two-bit abreviation. |
1413 MaxRecordsInBlock = NumBytesDefiningFunction * (CHAR_BIT >> 1); | 1417 MaxRecordsInBlock = NumBytesDefiningFunction * (CHAR_BIT >> 1); |
(...skipping 1172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2586 } | 2590 } |
2587 CurrentNode->appendInst(Phi); | 2591 CurrentNode->appendInst(Phi); |
2588 return; | 2592 return; |
2589 } | 2593 } |
2590 case naclbitc::FUNC_CODE_INST_ALLOCA: { | 2594 case naclbitc::FUNC_CODE_INST_ALLOCA: { |
2591 // ALLOCA: [Size, align] | 2595 // ALLOCA: [Size, align] |
2592 if (!isValidRecordSize(2, "alloca")) | 2596 if (!isValidRecordSize(2, "alloca")) |
2593 return; | 2597 return; |
2594 Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex); | 2598 Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex); |
2595 uint32_t Alignment; | 2599 uint32_t Alignment; |
2596 extractAlignment("Alloca", Values[1], Alignment); | 2600 Context->extractAlignment(this, "Alloca", Values[1], Alignment); |
2597 if (isIRGenerationDisabled()) { | 2601 if (isIRGenerationDisabled()) { |
2598 assert(ByteCount == nullptr); | 2602 assert(ByteCount == nullptr); |
2599 setNextLocalInstIndex(nullptr); | 2603 setNextLocalInstIndex(nullptr); |
2600 return; | 2604 return; |
2601 } | 2605 } |
2602 Ice::Type PtrTy = Ice::getPointerType(); | 2606 Ice::Type PtrTy = Ice::getPointerType(); |
2603 if (ByteCount->getType() != Ice::IceType_i32) { | 2607 if (ByteCount->getType() != Ice::IceType_i32) { |
2604 std::string Buffer; | 2608 std::string Buffer; |
2605 raw_string_ostream StrBuf(Buffer); | 2609 raw_string_ostream StrBuf(Buffer); |
2606 StrBuf << "Alloca on non-i32 value. Found: " << *ByteCount; | 2610 StrBuf << "Alloca on non-i32 value. Found: " << *ByteCount; |
2607 Error(StrBuf.str()); | 2611 Error(StrBuf.str()); |
2608 appendErrorInstruction(PtrTy); | 2612 appendErrorInstruction(PtrTy); |
2609 return; | 2613 return; |
2610 } | 2614 } |
2611 CurrentNode->appendInst(Ice::InstAlloca::create( | 2615 CurrentNode->appendInst(Ice::InstAlloca::create( |
2612 Func.get(), ByteCount, Alignment, getNextInstVar(PtrTy))); | 2616 Func.get(), ByteCount, Alignment, getNextInstVar(PtrTy))); |
2613 return; | 2617 return; |
2614 } | 2618 } |
2615 case naclbitc::FUNC_CODE_INST_LOAD: { | 2619 case naclbitc::FUNC_CODE_INST_LOAD: { |
2616 // LOAD: [address, align, ty] | 2620 // LOAD: [address, align, ty] |
2617 if (!isValidRecordSize(3, "load")) | 2621 if (!isValidRecordSize(3, "load")) |
2618 return; | 2622 return; |
2619 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); | 2623 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); |
2620 Ice::Type Ty = Context->getSimpleTypeByID(Values[2]); | 2624 Ice::Type Ty = Context->getSimpleTypeByID(Values[2]); |
2621 uint32_t Alignment; | 2625 uint32_t Alignment; |
2622 extractAlignment("Load", Values[1], Alignment); | 2626 Context->extractAlignment(this, "Load", Values[1], Alignment); |
2623 if (isIRGenerationDisabled()) { | 2627 if (isIRGenerationDisabled()) { |
2624 assert(Address == nullptr); | 2628 assert(Address == nullptr); |
2625 setNextLocalInstIndex(nullptr); | 2629 setNextLocalInstIndex(nullptr); |
2626 return; | 2630 return; |
2627 } | 2631 } |
2628 if (!isValidPointerType(Address, "Load")) { | 2632 if (!isValidPointerType(Address, "Load")) { |
2629 appendErrorInstruction(Ty); | 2633 appendErrorInstruction(Ty); |
2630 return; | 2634 return; |
2631 } | 2635 } |
2632 if (!isValidLoadStoreAlignment(Alignment, Ty, "Load")) { | 2636 if (!isValidLoadStoreAlignment(Alignment, Ty, "Load")) { |
2633 appendErrorInstruction(Ty); | 2637 appendErrorInstruction(Ty); |
2634 return; | 2638 return; |
2635 } | 2639 } |
2636 CurrentNode->appendInst(Ice::InstLoad::create( | 2640 CurrentNode->appendInst(Ice::InstLoad::create( |
2637 Func.get(), getNextInstVar(Ty), Address, Alignment)); | 2641 Func.get(), getNextInstVar(Ty), Address, Alignment)); |
2638 return; | 2642 return; |
2639 } | 2643 } |
2640 case naclbitc::FUNC_CODE_INST_STORE: { | 2644 case naclbitc::FUNC_CODE_INST_STORE: { |
2641 // STORE: [address, value, align] | 2645 // STORE: [address, value, align] |
2642 if (!isValidRecordSize(3, "store")) | 2646 if (!isValidRecordSize(3, "store")) |
2643 return; | 2647 return; |
2644 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); | 2648 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); |
2645 Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex); | 2649 Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex); |
2646 uint32_t Alignment; | 2650 uint32_t Alignment; |
2647 extractAlignment("Store", Values[2], Alignment); | 2651 Context->extractAlignment(this, "Store", Values[2], Alignment); |
2648 if (isIRGenerationDisabled()) { | 2652 if (isIRGenerationDisabled()) { |
2649 assert(Address == nullptr && Value == nullptr); | 2653 assert(Address == nullptr && Value == nullptr); |
2650 return; | 2654 return; |
2651 } | 2655 } |
2652 if (!isValidPointerType(Address, "Store")) | 2656 if (!isValidPointerType(Address, "Store")) |
2653 return; | 2657 return; |
2654 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store")) | 2658 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store")) |
2655 return; | 2659 return; |
2656 CurrentNode->appendInst( | 2660 CurrentNode->appendInst( |
2657 Ice::InstStore::create(Func.get(), Value, Address, Alignment)); | 2661 Ice::InstStore::create(Func.get(), Value, Address, Alignment)); |
(...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3282 raw_string_ostream StrBuf(Buffer); | 3286 raw_string_ostream StrBuf(Buffer); |
3283 StrBuf << IRFilename << ": Does not contain a module!"; | 3287 StrBuf << IRFilename << ": Does not contain a module!"; |
3284 llvm::report_fatal_error(StrBuf.str()); | 3288 llvm::report_fatal_error(StrBuf.str()); |
3285 } | 3289 } |
3286 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { | 3290 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { |
3287 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); | 3291 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); |
3288 } | 3292 } |
3289 } | 3293 } |
3290 | 3294 |
3291 } // end of namespace Ice | 3295 } // end of namespace Ice |
OLD | NEW |