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 |
11 /// This file implements the PNaCl bitcode file to Ice, to machine code | 11 /// This file implements the PNaCl bitcode file to Ice, to machine code |
12 /// translator. | 12 /// translator. |
13 /// | 13 /// |
14 //===----------------------------------------------------------------------===// | 14 //===----------------------------------------------------------------------===// |
15 | 15 |
16 #include "PNaClTranslator.h" | 16 #include "PNaClTranslator.h" |
17 | 17 |
18 #include "IceAPInt.h" | 18 #include "IceAPInt.h" |
19 #include "IceAPFloat.h" | 19 #include "IceAPFloat.h" |
20 #include "IceCfg.h" | 20 #include "IceCfg.h" |
21 #include "IceCfgNode.h" | 21 #include "IceCfgNode.h" |
22 #include "IceClFlags.h" | 22 #include "IceClFlags.h" |
23 #include "IceDefs.h" | 23 #include "IceDefs.h" |
24 #include "IceGlobalInits.h" | 24 #include "IceGlobalInits.h" |
25 #include "IceInst.h" | 25 #include "IceInst.h" |
26 #include "IceOperand.h" | 26 #include "IceOperand.h" |
27 | 27 |
28 #pragma clang diagnostic push | 28 #pragma clang diagnostic push |
29 #pragma clang diagnostic ignored "-Wunused-parameter" | 29 #pragma clang diagnostic ignored "-Wunused-parameter" |
30 #include "llvm/ADT/Hashing.h" | |
30 #include "llvm/ADT/SmallString.h" | 31 #include "llvm/ADT/SmallString.h" |
31 #include "llvm/Bitcode/NaCl/NaClBitcodeDecoders.h" | 32 #include "llvm/Bitcode/NaCl/NaClBitcodeDecoders.h" |
32 #include "llvm/Bitcode/NaCl/NaClBitcodeDefs.h" | 33 #include "llvm/Bitcode/NaCl/NaClBitcodeDefs.h" |
33 #include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h" | 34 #include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h" |
34 #include "llvm/Bitcode/NaCl/NaClBitcodeParser.h" | 35 #include "llvm/Bitcode/NaCl/NaClBitcodeParser.h" |
35 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h" | 36 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h" |
36 #include "llvm/Support/Format.h" | 37 #include "llvm/Support/Format.h" |
37 #include "llvm/Support/MemoryBuffer.h" | 38 #include "llvm/Support/MemoryBuffer.h" |
38 #include "llvm/Support/raw_ostream.h" | 39 #include "llvm/Support/raw_ostream.h" |
40 #include <unordered_set> | |
39 #pragma clang diagnostic pop | 41 #pragma clang diagnostic pop |
40 | 42 |
43 // Define a hash function for SmallString's, so that it can be used in hash | |
44 // tables. | |
45 namespace std { | |
46 template <unsigned InternalLen> struct hash<llvm::SmallString<InternalLen>> { | |
47 size_t operator()(const llvm::SmallString<InternalLen> &Key) const { | |
48 return llvm::hash_combine_range(Key.begin(), Key.end()); | |
49 } | |
50 }; | |
51 } // end of namespace std. | |
Jim Stichnoth
2015/09/16 19:54:37
no period, for consistency
Karl
2015/09/16 20:51:43
Done.
| |
52 | |
41 namespace { | 53 namespace { |
42 using namespace llvm; | 54 using namespace llvm; |
43 | 55 |
44 // Models elements in the list of types defined in the types block. | 56 // Models elements in the list of types defined in the types block. |
45 // These elements can be undefined, a (simple) type, or a function type | 57 // These elements can be undefined, a (simple) type, or a function type |
46 // signature. Note that an extended type is undefined on construction. | 58 // signature. Note that an extended type is undefined on construction. |
47 // Use methods setAsSimpleType and setAsFuncSigType to define | 59 // Use methods setAsSimpleType and setAsFuncSigType to define |
48 // the extended type. | 60 // the extended type. |
49 class ExtendedType { | 61 class ExtendedType { |
50 ExtendedType &operator=(const ExtendedType &Ty) = delete; | 62 ExtendedType &operator=(const ExtendedType &Ty) = delete; |
(...skipping 1102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1153 ValuesymtabParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) | 1165 ValuesymtabParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) |
1154 : BlockParserBaseClass(BlockID, EnclosingParser) {} | 1166 : BlockParserBaseClass(BlockID, EnclosingParser) {} |
1155 | 1167 |
1156 ~ValuesymtabParser() override = default; | 1168 ~ValuesymtabParser() override = default; |
1157 | 1169 |
1158 const char *getBlockName() const override { return "valuesymtab"; } | 1170 const char *getBlockName() const override { return "valuesymtab"; } |
1159 | 1171 |
1160 protected: | 1172 protected: |
1161 using StringType = SmallString<128>; | 1173 using StringType = SmallString<128>; |
1162 | 1174 |
1175 // Returns the name to identify the kind of symbol table this is | |
1176 // in error messages. | |
1177 virtual const char *getTableKind() const = 0; | |
1178 | |
1163 // Associates Name with the value defined by the given Index. | 1179 // Associates Name with the value defined by the given Index. |
1164 virtual void setValueName(NaClBcIndexSize_t Index, StringType &Name) = 0; | 1180 virtual void setValueName(NaClBcIndexSize_t Index, StringType &Name) = 0; |
1165 | 1181 |
1166 // Associates Name with the value defined by the given Index; | 1182 // Associates Name with the value defined by the given Index; |
1167 virtual void setBbName(NaClBcIndexSize_t Index, StringType &Name) = 0; | 1183 virtual void setBbName(NaClBcIndexSize_t Index, StringType &Name) = 0; |
1168 | 1184 |
1185 // Reports that the assignment of Name to the value associated with | |
1186 // index is not possible, for the given Context. | |
1187 void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index, | |
1188 StringType &Name); | |
1189 | |
1169 private: | 1190 private: |
1191 using NamesSetType = std::unordered_set<StringType>; | |
1192 NamesSetType ValueNames; | |
1193 NamesSetType BlockNames; | |
1194 | |
1170 void ProcessRecord() override; | 1195 void ProcessRecord() override; |
1171 | 1196 |
1172 void convertToString(StringType &ConvertedName) { | 1197 // Extracts out ConvertedName. Returns true if unique wrt to Names. |
1198 bool convertToString(NamesSetType &Names, StringType &ConvertedName) { | |
1173 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); | 1199 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
1174 for (size_t i = 1, e = Values.size(); i != e; ++i) { | 1200 for (size_t i = 1, e = Values.size(); i != e; ++i) { |
1175 ConvertedName += static_cast<char>(Values[i]); | 1201 ConvertedName += static_cast<char>(Values[i]); |
1176 } | 1202 } |
1203 auto Pair = Names.insert(ConvertedName); | |
1204 return Pair.second; | |
1177 } | 1205 } |
1206 | |
1207 void ReportDuplicateName(const char *NameCat, StringType &Name); | |
1178 }; | 1208 }; |
1179 | 1209 |
1210 void ValuesymtabParser::reportUnableToAssign(const char *Context, | |
1211 NaClBcIndexSize_t Index, | |
1212 StringType &Name) { | |
1213 std::string Buffer; | |
1214 raw_string_ostream StrBuf(Buffer); | |
1215 StrBuf << getTableKind() << " " << getBlockName() << ": " << Context | |
1216 << " name '" << Name << "' can't be associated with index " << Index; | |
1217 Error(StrBuf.str()); | |
1218 } | |
1219 | |
1220 void ValuesymtabParser::ReportDuplicateName(const char *NameCat, | |
1221 StringType &Name) { | |
1222 std::string Buffer; | |
1223 raw_string_ostream StrBuf(Buffer); | |
1224 StrBuf << getTableKind() << " " << getBlockName() << " defines duplicate " | |
1225 << NameCat << " name: '" << Name << "'"; | |
1226 Error(StrBuf.str()); | |
1227 } | |
1228 | |
1180 void ValuesymtabParser::ProcessRecord() { | 1229 void ValuesymtabParser::ProcessRecord() { |
1181 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); | 1230 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
1182 StringType ConvertedName; | 1231 StringType ConvertedName; |
1183 switch (Record.GetCode()) { | 1232 switch (Record.GetCode()) { |
1184 case naclbitc::VST_CODE_ENTRY: { | 1233 case naclbitc::VST_CODE_ENTRY: { |
1185 // VST_ENTRY: [ValueId, namechar x N] | 1234 // VST_ENTRY: [ValueId, namechar x N] |
1186 if (!isValidRecordSizeAtLeast(2, "value entry")) | 1235 if (!isValidRecordSizeAtLeast(2, "value entry")) |
1187 return; | 1236 return; |
1188 convertToString(ConvertedName); | 1237 if (convertToString(ValueNames, ConvertedName)) |
1189 setValueName(Values[0], ConvertedName); | 1238 setValueName(Values[0], ConvertedName); |
1239 else | |
1240 ReportDuplicateName("value", ConvertedName); | |
1190 return; | 1241 return; |
1191 } | 1242 } |
1192 case naclbitc::VST_CODE_BBENTRY: { | 1243 case naclbitc::VST_CODE_BBENTRY: { |
1193 // VST_BBENTRY: [BbId, namechar x N] | 1244 // VST_BBENTRY: [BbId, namechar x N] |
1194 if (!isValidRecordSizeAtLeast(2, "basic block entry")) | 1245 if (!isValidRecordSizeAtLeast(2, "basic block entry")) |
1195 return; | 1246 return; |
1196 convertToString(ConvertedName); | 1247 if (convertToString(BlockNames, ConvertedName)) |
1197 setBbName(Values[0], ConvertedName); | 1248 setBbName(Values[0], ConvertedName); |
1249 else | |
1250 ReportDuplicateName("block", ConvertedName); | |
1198 return; | 1251 return; |
1199 } | 1252 } |
1200 default: | 1253 default: |
1201 break; | 1254 break; |
1202 } | 1255 } |
1203 // If reached, don't know how to handle record. | 1256 // If reached, don't know how to handle record. |
1204 BlockParserBaseClass::ProcessRecord(); | 1257 BlockParserBaseClass::ProcessRecord(); |
1205 return; | 1258 return; |
1206 } | 1259 } |
1207 | 1260 |
(...skipping 1669 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2877 Timer(Ice::TimerStack::TT_parseFunctionValuesymtabs, | 2930 Timer(Ice::TimerStack::TT_parseFunctionValuesymtabs, |
2878 getTranslator().getContext()) {} | 2931 getTranslator().getContext()) {} |
2879 | 2932 |
2880 private: | 2933 private: |
2881 Ice::TimerMarker Timer; | 2934 Ice::TimerMarker Timer; |
2882 // Returns the enclosing function parser. | 2935 // Returns the enclosing function parser. |
2883 FunctionParser *getFunctionParser() const { | 2936 FunctionParser *getFunctionParser() const { |
2884 return reinterpret_cast<FunctionParser *>(GetEnclosingParser()); | 2937 return reinterpret_cast<FunctionParser *>(GetEnclosingParser()); |
2885 } | 2938 } |
2886 | 2939 |
2887 void setValueName(NaClBcIndexSize_t Index, StringType &Name) override; | 2940 const char *getTableKind() const final { return "Function"; } |
2888 void setBbName(NaClBcIndexSize_t Index, StringType &Name) override; | |
2889 | 2941 |
2890 // Reports that the assignment of Name to the value associated with | 2942 void setValueName(NaClBcIndexSize_t Index, StringType &Name) final; |
2891 // index is not possible, for the given Context. | 2943 void setBbName(NaClBcIndexSize_t Index, StringType &Name) final; |
2892 void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index, | |
2893 StringType &Name) { | |
2894 std::string Buffer; | |
2895 raw_string_ostream StrBuf(Buffer); | |
2896 StrBuf << "Function-local " << Context << " name '" << Name | |
2897 << "' can't be associated with index " << Index; | |
2898 Error(StrBuf.str()); | |
2899 } | |
2900 }; | 2944 }; |
2901 | 2945 |
2902 void FunctionValuesymtabParser::setValueName(NaClBcIndexSize_t Index, | 2946 void FunctionValuesymtabParser::setValueName(NaClBcIndexSize_t Index, |
2903 StringType &Name) { | 2947 StringType &Name) { |
2904 // Note: We check when Index is too small, so that we can error recover | 2948 // Note: We check when Index is too small, so that we can error recover |
2905 // (FP->getOperand will create fatal error). | 2949 // (FP->getOperand will create fatal error). |
2906 if (Index < getFunctionParser()->getNumGlobalIDs()) { | 2950 if (Index < getFunctionParser()->getNumGlobalIDs()) { |
2907 reportUnableToAssign("instruction", Index, Name); | 2951 reportUnableToAssign("Global value", Index, Name); |
2908 return; | 2952 return; |
2909 } | 2953 } |
2910 if (isIRGenerationDisabled()) | 2954 if (isIRGenerationDisabled()) |
2911 return; | 2955 return; |
2912 Ice::Operand *Op = getFunctionParser()->getOperand(Index); | 2956 Ice::Operand *Op = getFunctionParser()->getOperand(Index); |
2913 if (Ice::Variable *V = dyn_cast<Ice::Variable>(Op)) { | 2957 if (Ice::Variable *V = dyn_cast<Ice::Variable>(Op)) { |
2914 if (Ice::BuildDefs::dump()) { | 2958 if (Ice::BuildDefs::dump()) { |
2915 std::string Nm(Name.data(), Name.size()); | 2959 std::string Nm(Name.data(), Name.size()); |
2916 V->setName(getFunctionParser()->getFunc(), Nm); | 2960 V->setName(getFunctionParser()->getFunc(), Nm); |
2917 } | 2961 } |
2918 } else { | 2962 } else { |
2919 reportUnableToAssign("variable", Index, Name); | 2963 reportUnableToAssign("Local value", Index, Name); |
2920 } | 2964 } |
2921 } | 2965 } |
2922 | 2966 |
2923 void FunctionValuesymtabParser::setBbName(NaClBcIndexSize_t Index, | 2967 void FunctionValuesymtabParser::setBbName(NaClBcIndexSize_t Index, |
2924 StringType &Name) { | 2968 StringType &Name) { |
2925 if (!Ice::BuildDefs::dump()) | 2969 if (!Ice::BuildDefs::dump()) |
2926 return; | 2970 return; |
2927 if (isIRGenerationDisabled()) | 2971 if (isIRGenerationDisabled()) |
2928 return; | 2972 return; |
2929 if (Index >= getFunctionParser()->getFunc()->getNumNodes()) { | 2973 if (Index >= getFunctionParser()->getFunc()->getNumNodes()) { |
2930 reportUnableToAssign("block", Index, Name); | 2974 reportUnableToAssign("Basic block", Index, Name); |
2931 return; | 2975 return; |
2932 } | 2976 } |
2933 std::string Nm(Name.data(), Name.size()); | 2977 std::string Nm(Name.data(), Name.size()); |
2934 if (Ice::BuildDefs::dump()) | 2978 if (Ice::BuildDefs::dump()) |
2935 getFunctionParser()->getFunc()->getNodes()[Index]->setName(Nm); | 2979 getFunctionParser()->getFunc()->getNodes()[Index]->setName(Nm); |
2936 } | 2980 } |
2937 | 2981 |
2938 bool FunctionParser::ParseBlock(unsigned BlockID) { | 2982 bool FunctionParser::ParseBlock(unsigned BlockID) { |
2939 switch (BlockID) { | 2983 switch (BlockID) { |
2940 case naclbitc::CONSTANTS_BLOCK_ID: { | 2984 case naclbitc::CONSTANTS_BLOCK_ID: { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3003 public: | 3047 public: |
3004 ModuleValuesymtabParser(unsigned BlockID, ModuleParser *MP) | 3048 ModuleValuesymtabParser(unsigned BlockID, ModuleParser *MP) |
3005 : ValuesymtabParser(BlockID, MP), | 3049 : ValuesymtabParser(BlockID, MP), |
3006 Timer(Ice::TimerStack::TT_parseModuleValuesymtabs, | 3050 Timer(Ice::TimerStack::TT_parseModuleValuesymtabs, |
3007 getTranslator().getContext()) {} | 3051 getTranslator().getContext()) {} |
3008 | 3052 |
3009 ~ModuleValuesymtabParser() override = default; | 3053 ~ModuleValuesymtabParser() override = default; |
3010 | 3054 |
3011 private: | 3055 private: |
3012 Ice::TimerMarker Timer; | 3056 Ice::TimerMarker Timer; |
3013 void setValueName(NaClBcIndexSize_t Index, StringType &Name) override; | 3057 const char *getTableKind() const final { return "Module"; } |
3014 void setBbName(NaClBcIndexSize_t Index, StringType &Name) override; | 3058 void setValueName(NaClBcIndexSize_t Index, StringType &Name) final; |
3059 void setBbName(NaClBcIndexSize_t Index, StringType &Name) final; | |
3015 }; | 3060 }; |
3016 | 3061 |
3017 void ModuleValuesymtabParser::setValueName(NaClBcIndexSize_t Index, | 3062 void ModuleValuesymtabParser::setValueName(NaClBcIndexSize_t Index, |
3018 StringType &Name) { | 3063 StringType &Name) { |
3019 Context->getGlobalDeclarationByID(Index) | 3064 Context->getGlobalDeclarationByID(Index) |
3020 ->setName(StringRef(Name.data(), Name.size())); | 3065 ->setName(StringRef(Name.data(), Name.size())); |
3021 } | 3066 } |
3022 | 3067 |
3023 void ModuleValuesymtabParser::setBbName(NaClBcIndexSize_t Index, | 3068 void ModuleValuesymtabParser::setBbName(NaClBcIndexSize_t Index, |
3024 StringType &Name) { | 3069 StringType &Name) { |
3025 std::string Buffer; | 3070 reportUnableToAssign("Basic block", Index, Name); |
3026 raw_string_ostream StrBuf(Buffer); | |
3027 StrBuf << "Can't define basic block name at global level: '" << Name | |
3028 << "' -> " << Index; | |
3029 Error(StrBuf.str()); | |
3030 } | 3071 } |
3031 | 3072 |
3032 bool ModuleParser::ParseBlock(unsigned BlockID) { | 3073 bool ModuleParser::ParseBlock(unsigned BlockID) { |
3033 switch (BlockID) { | 3074 switch (BlockID) { |
3034 case naclbitc::BLOCKINFO_BLOCK_ID: | 3075 case naclbitc::BLOCKINFO_BLOCK_ID: |
3035 return NaClBitcodeParser::ParseBlock(BlockID); | 3076 return NaClBitcodeParser::ParseBlock(BlockID); |
3036 case naclbitc::TYPE_BLOCK_ID_NEW: { | 3077 case naclbitc::TYPE_BLOCK_ID_NEW: { |
3037 TypesParser Parser(BlockID, this); | 3078 TypesParser Parser(BlockID, this); |
3038 return Parser.ParseThisBlock(); | 3079 return Parser.ParseThisBlock(); |
3039 } | 3080 } |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3171 } | 3212 } |
3172 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { | 3213 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { |
3173 ErrStream | 3214 ErrStream |
3174 << IRFilename | 3215 << IRFilename |
3175 << ": Bitcode stream should be a multiple of 4 bytes in length.\n"; | 3216 << ": Bitcode stream should be a multiple of 4 bytes in length.\n"; |
3176 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); | 3217 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); |
3177 } | 3218 } |
3178 } | 3219 } |
3179 | 3220 |
3180 } // end of namespace Ice | 3221 } // end of namespace Ice |
OLD | NEW |