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 constexpr uint32_t AlignPowerLimit = 29; |
| 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 uint32_t extractAlignment(NaClBitcodeParser *Parser, const char *Prefix, |
| 363 uint32_t AlignPower) { |
| 364 if (AlignPower <= AlignPowerLimit + 1) |
| 365 return (1 << AlignPower) >> 1; |
| 366 std::string Buffer; |
| 367 raw_string_ostream StrBuf(Buffer); |
| 368 StrBuf << Prefix << " alignment greater than 2**" << AlignPowerLimit |
| 369 << ". Found: 2**" << (AlignPower - 1); |
| 370 Parser->Error(StrBuf.str()); |
| 371 // Error recover with value that is always acceptable. |
| 372 return 1; |
| 373 } |
| 374 |
355 private: | 375 private: |
356 // The translator associated with the parser. | 376 // The translator associated with the parser. |
357 Ice::Translator &Translator; | 377 Ice::Translator &Translator; |
358 // The exit status that should be set to true if an error occurs. | 378 // The exit status that should be set to true if an error occurs. |
359 Ice::ErrorCode &ErrorStatus; | 379 Ice::ErrorCode &ErrorStatus; |
360 // The number of errors reported. | 380 // The number of errors reported. |
361 unsigned NumErrors = 0; | 381 unsigned NumErrors = 0; |
362 // The types associated with each type ID. | 382 // The types associated with each type ID. |
363 std::vector<ExtendedType> TypeIDValues; | 383 std::vector<ExtendedType> TypeIDValues; |
364 // The set of functions (prototype and defined). | 384 // The set of functions (prototype and defined). |
(...skipping 689 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1054 SpecifiedNumberVars = Values[0]; | 1074 SpecifiedNumberVars = Values[0]; |
1055 return; | 1075 return; |
1056 case naclbitc::GLOBALVAR_VAR: { | 1076 case naclbitc::GLOBALVAR_VAR: { |
1057 // VAR: [align, isconst] | 1077 // VAR: [align, isconst] |
1058 if (!isValidRecordSize(2, "variable")) | 1078 if (!isValidRecordSize(2, "variable")) |
1059 return; | 1079 return; |
1060 verifyNoMissingInitializers(); | 1080 verifyNoMissingInitializers(); |
1061 // Always build the global variable, even if IR generation is turned off. | 1081 // 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 | 1082 // This is needed because we need a placeholder in the top-level context |
1063 // when no IR is generated. | 1083 // when no IR is generated. |
| 1084 uint32_t Alignment = |
| 1085 Context->extractAlignment(this, "Global variable", Values[0]); |
1064 CurGlobalVar = getGlobalVarByID(NextGlobalID); | 1086 CurGlobalVar = getGlobalVarByID(NextGlobalID); |
1065 if (!isIRGenerationDisabled()) { | 1087 if (!isIRGenerationDisabled()) { |
1066 InitializersNeeded = 1; | 1088 InitializersNeeded = 1; |
1067 CurGlobalVar->setAlignment((1 << Values[0]) >> 1); | 1089 CurGlobalVar->setAlignment(Alignment); |
1068 CurGlobalVar->setIsConstant(Values[1] != 0); | 1090 CurGlobalVar->setIsConstant(Values[1] != 0); |
1069 } | 1091 } |
1070 ++NextGlobalID; | 1092 ++NextGlobalID; |
1071 return; | 1093 return; |
1072 } | 1094 } |
1073 case naclbitc::GLOBALVAR_COMPOUND: | 1095 case naclbitc::GLOBALVAR_COMPOUND: |
1074 // COMPOUND: [size] | 1096 // COMPOUND: [size] |
1075 if (!isValidRecordSize(1, "compound")) | 1097 if (!isValidRecordSize(1, "compound")) |
1076 return; | 1098 return; |
1077 if (!CurGlobalVar->getInitializers().empty()) { | 1099 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. | 1396 // Holds the dividing point between local and global absolute value indices. |
1375 size_t CachedNumGlobalValueIDs; | 1397 size_t CachedNumGlobalValueIDs; |
1376 // Holds operands local to the function block, based on indices defined in | 1398 // Holds operands local to the function block, based on indices defined in |
1377 // the bitcode file. | 1399 // the bitcode file. |
1378 Ice::OperandList LocalOperands; | 1400 Ice::OperandList LocalOperands; |
1379 // Holds the index within LocalOperands corresponding to the next instruction | 1401 // Holds the index within LocalOperands corresponding to the next instruction |
1380 // that generates a value. | 1402 // that generates a value. |
1381 NaClBcIndexSize_t NextLocalInstIndex; | 1403 NaClBcIndexSize_t NextLocalInstIndex; |
1382 // True if the last processed instruction was a terminating instruction. | 1404 // True if the last processed instruction was a terminating instruction. |
1383 bool InstIsTerminating = false; | 1405 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 | 1406 |
1405 bool ParseBlock(unsigned BlockID) override; | 1407 bool ParseBlock(unsigned BlockID) override; |
1406 | 1408 |
1407 void ProcessRecord() override; | 1409 void ProcessRecord() override; |
1408 | 1410 |
1409 void EnterBlock(unsigned NumWords) final { | 1411 void EnterBlock(unsigned NumWords) final { |
1410 // Note: Bitstream defines words as 32-bit values. | 1412 // Note: Bitstream defines words as 32-bit values. |
1411 NumBytesDefiningFunction = NumWords * sizeof(uint32_t); | 1413 NumBytesDefiningFunction = NumWords * sizeof(uint32_t); |
1412 // We know that all records are minimally defined by a two-bit abreviation. | 1414 // We know that all records are minimally defined by a two-bit abreviation. |
1413 MaxRecordsInBlock = NumBytesDefiningFunction * (CHAR_BIT >> 1); | 1415 MaxRecordsInBlock = NumBytesDefiningFunction * (CHAR_BIT >> 1); |
(...skipping 1171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2585 Phi->addArgument(Op, getBasicBlock(Values[i + 1])); | 2587 Phi->addArgument(Op, getBasicBlock(Values[i + 1])); |
2586 } | 2588 } |
2587 CurrentNode->appendInst(Phi); | 2589 CurrentNode->appendInst(Phi); |
2588 return; | 2590 return; |
2589 } | 2591 } |
2590 case naclbitc::FUNC_CODE_INST_ALLOCA: { | 2592 case naclbitc::FUNC_CODE_INST_ALLOCA: { |
2591 // ALLOCA: [Size, align] | 2593 // ALLOCA: [Size, align] |
2592 if (!isValidRecordSize(2, "alloca")) | 2594 if (!isValidRecordSize(2, "alloca")) |
2593 return; | 2595 return; |
2594 Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex); | 2596 Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex); |
2595 uint32_t Alignment; | 2597 uint32_t Alignment = Context->extractAlignment(this, "Alloca", Values[1]); |
2596 extractAlignment("Alloca", Values[1], Alignment); | |
2597 if (isIRGenerationDisabled()) { | 2598 if (isIRGenerationDisabled()) { |
2598 assert(ByteCount == nullptr); | 2599 assert(ByteCount == nullptr); |
2599 setNextLocalInstIndex(nullptr); | 2600 setNextLocalInstIndex(nullptr); |
2600 return; | 2601 return; |
2601 } | 2602 } |
2602 Ice::Type PtrTy = Ice::getPointerType(); | 2603 Ice::Type PtrTy = Ice::getPointerType(); |
2603 if (ByteCount->getType() != Ice::IceType_i32) { | 2604 if (ByteCount->getType() != Ice::IceType_i32) { |
2604 std::string Buffer; | 2605 std::string Buffer; |
2605 raw_string_ostream StrBuf(Buffer); | 2606 raw_string_ostream StrBuf(Buffer); |
2606 StrBuf << "Alloca on non-i32 value. Found: " << *ByteCount; | 2607 StrBuf << "Alloca on non-i32 value. Found: " << *ByteCount; |
2607 Error(StrBuf.str()); | 2608 Error(StrBuf.str()); |
2608 appendErrorInstruction(PtrTy); | 2609 appendErrorInstruction(PtrTy); |
2609 return; | 2610 return; |
2610 } | 2611 } |
2611 CurrentNode->appendInst(Ice::InstAlloca::create( | 2612 CurrentNode->appendInst(Ice::InstAlloca::create( |
2612 Func.get(), ByteCount, Alignment, getNextInstVar(PtrTy))); | 2613 Func.get(), ByteCount, Alignment, getNextInstVar(PtrTy))); |
2613 return; | 2614 return; |
2614 } | 2615 } |
2615 case naclbitc::FUNC_CODE_INST_LOAD: { | 2616 case naclbitc::FUNC_CODE_INST_LOAD: { |
2616 // LOAD: [address, align, ty] | 2617 // LOAD: [address, align, ty] |
2617 if (!isValidRecordSize(3, "load")) | 2618 if (!isValidRecordSize(3, "load")) |
2618 return; | 2619 return; |
2619 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); | 2620 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); |
2620 Ice::Type Ty = Context->getSimpleTypeByID(Values[2]); | 2621 Ice::Type Ty = Context->getSimpleTypeByID(Values[2]); |
2621 uint32_t Alignment; | 2622 uint32_t Alignment = Context->extractAlignment(this, "Load", Values[1]); |
2622 extractAlignment("Load", Values[1], Alignment); | |
2623 if (isIRGenerationDisabled()) { | 2623 if (isIRGenerationDisabled()) { |
2624 assert(Address == nullptr); | 2624 assert(Address == nullptr); |
2625 setNextLocalInstIndex(nullptr); | 2625 setNextLocalInstIndex(nullptr); |
2626 return; | 2626 return; |
2627 } | 2627 } |
2628 if (!isValidPointerType(Address, "Load")) { | 2628 if (!isValidPointerType(Address, "Load")) { |
2629 appendErrorInstruction(Ty); | 2629 appendErrorInstruction(Ty); |
2630 return; | 2630 return; |
2631 } | 2631 } |
2632 if (!isValidLoadStoreAlignment(Alignment, Ty, "Load")) { | 2632 if (!isValidLoadStoreAlignment(Alignment, Ty, "Load")) { |
2633 appendErrorInstruction(Ty); | 2633 appendErrorInstruction(Ty); |
2634 return; | 2634 return; |
2635 } | 2635 } |
2636 CurrentNode->appendInst(Ice::InstLoad::create( | 2636 CurrentNode->appendInst(Ice::InstLoad::create( |
2637 Func.get(), getNextInstVar(Ty), Address, Alignment)); | 2637 Func.get(), getNextInstVar(Ty), Address, Alignment)); |
2638 return; | 2638 return; |
2639 } | 2639 } |
2640 case naclbitc::FUNC_CODE_INST_STORE: { | 2640 case naclbitc::FUNC_CODE_INST_STORE: { |
2641 // STORE: [address, value, align] | 2641 // STORE: [address, value, align] |
2642 if (!isValidRecordSize(3, "store")) | 2642 if (!isValidRecordSize(3, "store")) |
2643 return; | 2643 return; |
2644 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); | 2644 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); |
2645 Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex); | 2645 Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex); |
2646 uint32_t Alignment; | 2646 uint32_t Alignment = Context->extractAlignment(this, "Store", Values[2]); |
2647 extractAlignment("Store", Values[2], Alignment); | |
2648 if (isIRGenerationDisabled()) { | 2647 if (isIRGenerationDisabled()) { |
2649 assert(Address == nullptr && Value == nullptr); | 2648 assert(Address == nullptr && Value == nullptr); |
2650 return; | 2649 return; |
2651 } | 2650 } |
2652 if (!isValidPointerType(Address, "Store")) | 2651 if (!isValidPointerType(Address, "Store")) |
2653 return; | 2652 return; |
2654 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store")) | 2653 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store")) |
2655 return; | 2654 return; |
2656 CurrentNode->appendInst( | 2655 CurrentNode->appendInst( |
2657 Ice::InstStore::create(Func.get(), Value, Address, Alignment)); | 2656 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); | 3281 raw_string_ostream StrBuf(Buffer); |
3283 StrBuf << IRFilename << ": Does not contain a module!"; | 3282 StrBuf << IRFilename << ": Does not contain a module!"; |
3284 llvm::report_fatal_error(StrBuf.str()); | 3283 llvm::report_fatal_error(StrBuf.str()); |
3285 } | 3284 } |
3286 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { | 3285 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { |
3287 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); | 3286 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); |
3288 } | 3287 } |
3289 } | 3288 } |
3290 | 3289 |
3291 } // end of namespace Ice | 3290 } // end of namespace Ice |
OLD | NEW |