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 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 /// Returns the number of global declarations (i.e. IDs) defined in | 299 /// Returns the number of global declarations (i.e. IDs) defined in |
300 /// the bitcode file. | 300 /// the bitcode file. |
301 size_t getNumGlobalIDs() const { | 301 size_t getNumGlobalIDs() const { |
302 if (VariableDeclarations) { | 302 if (VariableDeclarations) { |
303 return FunctionDeclarationList.size() + VariableDeclarations->size(); | 303 return FunctionDeclarationList.size() + VariableDeclarations->size(); |
304 } else { | 304 } else { |
305 return ValueIDConstants.size(); | 305 return ValueIDConstants.size(); |
306 } | 306 } |
307 } | 307 } |
308 | 308 |
309 /// Creates Count global variable declarations. | 309 /// Adds the given global declaration to the end of the list of global |
310 void createGlobalVariables(NaClBcIndexSize_t Count) { | 310 /// declarations. |
| 311 void addGlobalDeclaration(Ice::VariableDeclaration *Decl) { |
311 assert(VariableDeclarations); | 312 assert(VariableDeclarations); |
312 assert(VariableDeclarations->empty()); | 313 VariableDeclarations->push_back(Decl); |
313 for (size_t i = 0; i < Count; ++i) { | |
314 VariableDeclarations->push_back( | |
315 Ice::VariableDeclaration::create(getTranslator().getContext())); | |
316 } | |
317 } | |
318 | |
319 /// Returns the number of global variable declarations in the | |
320 /// bitcode file. | |
321 size_t getNumGlobalVariables() const { | |
322 if (VariableDeclarations) { | |
323 return VariableDeclarations->size(); | |
324 } else { | |
325 return ValueIDConstants.size() - FunctionDeclarationList.size(); | |
326 } | |
327 } | 314 } |
328 | 315 |
329 /// Returns the global variable declaration with the given index. | 316 /// Returns the global variable declaration with the given index. |
330 Ice::VariableDeclaration *getGlobalVariableByID(NaClBcIndexSize_t Index) { | 317 Ice::VariableDeclaration *getGlobalVariableByID(NaClBcIndexSize_t Index) { |
331 assert(VariableDeclarations); | 318 assert(VariableDeclarations); |
332 if (Index < VariableDeclarations->size()) | 319 if (Index < VariableDeclarations->size()) |
333 return VariableDeclarations->at(Index); | 320 return VariableDeclarations->at(Index); |
334 return reportGetGlobalVariableByIDError(Index); | 321 return reportGetGlobalVariableByIDError(Index); |
335 } | 322 } |
336 | 323 |
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
948 /// corresponding initializers). | 935 /// corresponding initializers). |
949 class GlobalsParser : public BlockParserBaseClass { | 936 class GlobalsParser : public BlockParserBaseClass { |
950 GlobalsParser() = delete; | 937 GlobalsParser() = delete; |
951 GlobalsParser(const GlobalsParser &) = delete; | 938 GlobalsParser(const GlobalsParser &) = delete; |
952 GlobalsParser &operator=(const GlobalsParser &) = delete; | 939 GlobalsParser &operator=(const GlobalsParser &) = delete; |
953 | 940 |
954 public: | 941 public: |
955 GlobalsParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) | 942 GlobalsParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) |
956 : BlockParserBaseClass(BlockID, EnclosingParser), | 943 : BlockParserBaseClass(BlockID, EnclosingParser), |
957 Timer(Ice::TimerStack::TT_parseGlobals, getTranslator().getContext()), | 944 Timer(Ice::TimerStack::TT_parseGlobals, getTranslator().getContext()), |
| 945 NumFunctionIDs(Context->getNumFunctionIDs()), |
958 DummyGlobalVar( | 946 DummyGlobalVar( |
959 Ice::VariableDeclaration::create(getTranslator().getContext())), | 947 Ice::VariableDeclaration::create(getTranslator().getContext())), |
960 CurGlobalVar(DummyGlobalVar) {} | 948 CurGlobalVar(DummyGlobalVar) {} |
961 | 949 |
962 ~GlobalsParser() final = default; | 950 ~GlobalsParser() final = default; |
963 | 951 |
964 const char *getBlockName() const override { return "globals"; } | 952 const char *getBlockName() const override { return "globals"; } |
965 | 953 |
966 private: | 954 private: |
| 955 typedef std::unordered_map<NaClBcIndexSize_t, Ice::VariableDeclaration *> |
| 956 GlobalVarsMapType; |
| 957 |
967 Ice::TimerMarker Timer; | 958 Ice::TimerMarker Timer; |
| 959 |
| 960 // Holds global variables generated/referenced in the global variables block. |
| 961 GlobalVarsMapType GlobalVarsMap; |
| 962 |
| 963 // Holds the number of defined function IDs. |
| 964 NaClBcIndexSize_t NumFunctionIDs; |
| 965 |
| 966 // Holds the specified number of global variables by the count record in |
| 967 // the global variables block. |
| 968 NaClBcIndexSize_t SpecifiedNumberVars = 0; |
| 969 |
968 // Keeps track of how many initializers are expected for the global variable | 970 // Keeps track of how many initializers are expected for the global variable |
969 // declaration being built. | 971 // declaration being built. |
970 NaClBcIndexSize_t InitializersNeeded = 0; | 972 NaClBcIndexSize_t InitializersNeeded = 0; |
971 | 973 |
972 // The index of the next global variable declaration. | 974 // The index of the next global variable declaration. |
973 NaClBcIndexSize_t NextGlobalID = 0; | 975 NaClBcIndexSize_t NextGlobalID = 0; |
974 | 976 |
975 // Dummy global variable declaration to guarantee CurGlobalVar is | 977 // Dummy global variable declaration to guarantee CurGlobalVar is |
976 // always defined (allowing code to not need to check if | 978 // always defined (allowing code to not need to check if |
977 // CurGlobalVar is nullptr). | 979 // CurGlobalVar is nullptr). |
978 Ice::VariableDeclaration *DummyGlobalVar; | 980 Ice::VariableDeclaration *DummyGlobalVar; |
979 | 981 |
980 // Holds the current global variable declaration being built. | 982 // Holds the current global variable declaration being built. |
981 Ice::VariableDeclaration *CurGlobalVar; | 983 Ice::VariableDeclaration *CurGlobalVar; |
982 | 984 |
| 985 // Returns the global variable associated with the given Index. |
| 986 Ice::VariableDeclaration *getGlobalVarByID(NaClBcIndexSize_t Index) { |
| 987 Ice::VariableDeclaration *&Decl = GlobalVarsMap[Index]; |
| 988 if (Decl == nullptr) |
| 989 Decl = Ice::VariableDeclaration::create(getTranslator().getContext()); |
| 990 return Decl; |
| 991 } |
| 992 |
| 993 // Returns the global declaration associated with the given index. |
| 994 Ice::GlobalDeclaration *getGlobalDeclByID(NaClBcIndexSize_t Index) { |
| 995 if (Index < NumFunctionIDs) |
| 996 return Context->getFunctionByID(Index); |
| 997 return getGlobalVarByID(Index - NumFunctionIDs); |
| 998 } |
| 999 |
| 1000 // If global variables parsed correctly, install them into the top-level |
| 1001 // context. |
| 1002 void installGlobalVariables() { |
| 1003 // Verify specified number of globals matches number found. |
| 1004 size_t NumGlobals = GlobalVarsMap.size(); |
| 1005 if (SpecifiedNumberVars != NumGlobals || |
| 1006 SpecifiedNumberVars != NextGlobalID) { |
| 1007 std::string Buffer; |
| 1008 raw_string_ostream StrBuf(Buffer); |
| 1009 StrBuf << getBlockName() << " block expects " << SpecifiedNumberVars |
| 1010 << " global variables. Found: " << GlobalVarsMap.size(); |
| 1011 Error(StrBuf.str()); |
| 1012 return; |
| 1013 } |
| 1014 // Install global variables into top-level context. |
| 1015 for (size_t I = 0; I < NumGlobals; ++I) |
| 1016 Context->addGlobalDeclaration(GlobalVarsMap[I]); |
| 1017 } |
| 1018 |
983 void ExitBlock() override { | 1019 void ExitBlock() override { |
984 verifyNoMissingInitializers(); | 1020 verifyNoMissingInitializers(); |
985 unsigned NumIDs = Context->getNumGlobalVariables(); | 1021 installGlobalVariables(); |
986 if (NextGlobalID < NumIDs) { | |
987 std::string Buffer; | |
988 raw_string_ostream StrBuf(Buffer); | |
989 StrBuf << getBlockName() << " block expects " << NumIDs | |
990 << " global variable declarations. Found: " << NextGlobalID; | |
991 Error(StrBuf.str()); | |
992 } | |
993 BlockParserBaseClass::ExitBlock(); | 1022 BlockParserBaseClass::ExitBlock(); |
994 } | 1023 } |
995 | 1024 |
996 void ProcessRecord() override; | 1025 void ProcessRecord() override; |
997 | 1026 |
998 // Checks if the number of initializers for the CurGlobalVar is the same as | 1027 // Checks if the number of initializers for the CurGlobalVar is the same as |
999 // the number found in the bitcode file. If different, and error message is | 1028 // the number found in the bitcode file. If different, and error message is |
1000 // generated, and the internal state of the parser is fixed so this condition | 1029 // generated, and the internal state of the parser is fixed so this condition |
1001 // is no longer violated. | 1030 // is no longer violated. |
1002 void verifyNoMissingInitializers() { | 1031 void verifyNoMissingInitializers() { |
(...skipping 12 matching lines...) Expand all Loading... |
1015 } | 1044 } |
1016 }; | 1045 }; |
1017 | 1046 |
1018 void GlobalsParser::ProcessRecord() { | 1047 void GlobalsParser::ProcessRecord() { |
1019 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); | 1048 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
1020 switch (Record.GetCode()) { | 1049 switch (Record.GetCode()) { |
1021 case naclbitc::GLOBALVAR_COUNT: | 1050 case naclbitc::GLOBALVAR_COUNT: |
1022 // COUNT: [n] | 1051 // COUNT: [n] |
1023 if (!isValidRecordSize(1, "count")) | 1052 if (!isValidRecordSize(1, "count")) |
1024 return; | 1053 return; |
1025 if (NextGlobalID != Context->getNumGlobalVariables()) { | 1054 if (SpecifiedNumberVars || NextGlobalID) { |
1026 Error("Globals count record not first in block."); | 1055 Error("Globals count record not first in block."); |
1027 return; | 1056 return; |
1028 } | 1057 } |
1029 Context->createGlobalVariables(Values[0]); | 1058 SpecifiedNumberVars = Values[0]; |
1030 return; | 1059 return; |
1031 case naclbitc::GLOBALVAR_VAR: { | 1060 case naclbitc::GLOBALVAR_VAR: { |
1032 // VAR: [align, isconst] | 1061 // VAR: [align, isconst] |
1033 if (!isValidRecordSize(2, "variable")) | 1062 if (!isValidRecordSize(2, "variable")) |
1034 return; | 1063 return; |
1035 verifyNoMissingInitializers(); | 1064 verifyNoMissingInitializers(); |
| 1065 // Always build the global variable, even if IR generation is turned off. |
| 1066 // This is needed because we need a placeholder in the top-level context |
| 1067 // when no IR is generated. |
| 1068 CurGlobalVar = getGlobalVarByID(NextGlobalID); |
1036 if (!isIRGenerationDisabled()) { | 1069 if (!isIRGenerationDisabled()) { |
1037 InitializersNeeded = 1; | 1070 InitializersNeeded = 1; |
1038 CurGlobalVar = Context->getGlobalVariableByID(NextGlobalID); | |
1039 CurGlobalVar->setAlignment((1 << Values[0]) >> 1); | 1071 CurGlobalVar->setAlignment((1 << Values[0]) >> 1); |
1040 CurGlobalVar->setIsConstant(Values[1] != 0); | 1072 CurGlobalVar->setIsConstant(Values[1] != 0); |
1041 } | 1073 } |
1042 ++NextGlobalID; | 1074 ++NextGlobalID; |
1043 return; | 1075 return; |
1044 } | 1076 } |
1045 case naclbitc::GLOBALVAR_COMPOUND: | 1077 case naclbitc::GLOBALVAR_COMPOUND: |
1046 // COMPOUND: [size] | 1078 // COMPOUND: [size] |
1047 if (!isValidRecordSize(1, "compound")) | 1079 if (!isValidRecordSize(1, "compound")) |
1048 return; | 1080 return; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1081 CurGlobalVar->addInitializer( | 1113 CurGlobalVar->addInitializer( |
1082 Ice::VariableDeclaration::DataInitializer::create(Values)); | 1114 Ice::VariableDeclaration::DataInitializer::create(Values)); |
1083 return; | 1115 return; |
1084 } | 1116 } |
1085 case naclbitc::GLOBALVAR_RELOC: { | 1117 case naclbitc::GLOBALVAR_RELOC: { |
1086 // RELOC: [val, [addend]] | 1118 // RELOC: [val, [addend]] |
1087 if (!isValidRecordSizeInRange(1, 2, "reloc")) | 1119 if (!isValidRecordSizeInRange(1, 2, "reloc")) |
1088 return; | 1120 return; |
1089 if (isIRGenerationDisabled()) | 1121 if (isIRGenerationDisabled()) |
1090 return; | 1122 return; |
1091 unsigned Index = Values[0]; | 1123 NaClBcIndexSize_t Index = Values[0]; |
| 1124 NaClBcIndexSize_t IndexLimit = SpecifiedNumberVars + NumFunctionIDs; |
| 1125 if (Index >= IndexLimit) { |
| 1126 std::string Buffer; |
| 1127 raw_string_ostream StrBuf(Buffer); |
| 1128 StrBuf << "Relocation index " << Index << " to big. Expect index < " |
| 1129 << IndexLimit; |
| 1130 Error(StrBuf.str()); |
| 1131 } |
1092 uint64_t Offset = 0; | 1132 uint64_t Offset = 0; |
1093 if (Values.size() == 2) { | 1133 if (Values.size() == 2) { |
1094 Offset = Values[1]; | 1134 Offset = Values[1]; |
1095 if (Offset > std::numeric_limits<uint32_t>::max()) { | 1135 if (Offset > std::numeric_limits<uint32_t>::max()) { |
1096 std::string Buffer; | 1136 std::string Buffer; |
1097 raw_string_ostream StrBuf(Buffer); | 1137 raw_string_ostream StrBuf(Buffer); |
1098 StrBuf << "Addend of global reloc record too big: " << Offset; | 1138 StrBuf << "Addend of global reloc record too big: " << Offset; |
1099 Error(StrBuf.str()); | 1139 Error(StrBuf.str()); |
1100 } | 1140 } |
1101 } | 1141 } |
1102 CurGlobalVar->addInitializer( | 1142 CurGlobalVar->addInitializer( |
1103 Ice::VariableDeclaration::RelocInitializer::create( | 1143 Ice::VariableDeclaration::RelocInitializer::create( |
1104 Context->getGlobalDeclarationByID(Index), Offset)); | 1144 getGlobalDeclByID(Index), Offset)); |
1105 return; | 1145 return; |
1106 } | 1146 } |
1107 default: | 1147 default: |
1108 BlockParserBaseClass::ProcessRecord(); | 1148 BlockParserBaseClass::ProcessRecord(); |
1109 return; | 1149 return; |
1110 } | 1150 } |
1111 } | 1151 } |
1112 | 1152 |
1113 /// Base class for parsing a valuesymtab block in the bitcode file. | 1153 /// Base class for parsing a valuesymtab block in the bitcode file. |
1114 class ValuesymtabParser : public BlockParserBaseClass { | 1154 class ValuesymtabParser : public BlockParserBaseClass { |
(...skipping 2025 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3140 } | 3180 } |
3141 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { | 3181 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { |
3142 ErrStream | 3182 ErrStream |
3143 << IRFilename | 3183 << IRFilename |
3144 << ": Bitcode stream should be a multiple of 4 bytes in length.\n"; | 3184 << ": Bitcode stream should be a multiple of 4 bytes in length.\n"; |
3145 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); | 3185 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); |
3146 } | 3186 } |
3147 } | 3187 } |
3148 | 3188 |
3149 } // end of namespace Ice | 3189 } // end of namespace Ice |
OLD | NEW |