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 |
| 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. These | 56 // Models elements in the list of types defined in the types block. These |
45 // elements can be undefined, a (simple) type, or a function type signature. | 57 // elements can be undefined, a (simple) type, or a function type signature. |
46 // Note that an extended type is undefined on construction. Use methods | 58 // Note that an extended type is undefined on construction. Use methods |
47 // setAsSimpleType and setAsFuncSigType to define the extended type. | 59 // setAsSimpleType and setAsFuncSigType to define the extended type. |
48 class ExtendedType { | 60 class ExtendedType { |
49 ExtendedType &operator=(const ExtendedType &Ty) = delete; | 61 ExtendedType &operator=(const ExtendedType &Ty) = delete; |
50 | 62 |
(...skipping 1088 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1139 ValuesymtabParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) | 1151 ValuesymtabParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) |
1140 : BlockParserBaseClass(BlockID, EnclosingParser) {} | 1152 : BlockParserBaseClass(BlockID, EnclosingParser) {} |
1141 | 1153 |
1142 ~ValuesymtabParser() override = default; | 1154 ~ValuesymtabParser() override = default; |
1143 | 1155 |
1144 const char *getBlockName() const override { return "valuesymtab"; } | 1156 const char *getBlockName() const override { return "valuesymtab"; } |
1145 | 1157 |
1146 protected: | 1158 protected: |
1147 using StringType = SmallString<128>; | 1159 using StringType = SmallString<128>; |
1148 | 1160 |
| 1161 // Returns the name to identify the kind of symbol table this is |
| 1162 // in error messages. |
| 1163 virtual const char *getTableKind() const = 0; |
| 1164 |
1149 // Associates Name with the value defined by the given Index. | 1165 // Associates Name with the value defined by the given Index. |
1150 virtual void setValueName(NaClBcIndexSize_t Index, StringType &Name) = 0; | 1166 virtual void setValueName(NaClBcIndexSize_t Index, StringType &Name) = 0; |
1151 | 1167 |
1152 // Associates Name with the value defined by the given Index; | 1168 // Associates Name with the value defined by the given Index; |
1153 virtual void setBbName(NaClBcIndexSize_t Index, StringType &Name) = 0; | 1169 virtual void setBbName(NaClBcIndexSize_t Index, StringType &Name) = 0; |
1154 | 1170 |
| 1171 // Reports that the assignment of Name to the value associated with |
| 1172 // index is not possible, for the given Context. |
| 1173 void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index, |
| 1174 StringType &Name); |
| 1175 |
1155 private: | 1176 private: |
| 1177 using NamesSetType = std::unordered_set<StringType>; |
| 1178 NamesSetType ValueNames; |
| 1179 NamesSetType BlockNames; |
| 1180 |
1156 void ProcessRecord() override; | 1181 void ProcessRecord() override; |
1157 | 1182 |
1158 void convertToString(StringType &ConvertedName) { | 1183 // Extracts out ConvertedName. Returns true if unique wrt to Names. |
| 1184 bool convertToString(NamesSetType &Names, StringType &ConvertedName) { |
1159 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); | 1185 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
1160 for (size_t i = 1, e = Values.size(); i != e; ++i) { | 1186 for (size_t i = 1, e = Values.size(); i != e; ++i) { |
1161 ConvertedName += static_cast<char>(Values[i]); | 1187 ConvertedName += static_cast<char>(Values[i]); |
1162 } | 1188 } |
| 1189 auto Pair = Names.insert(ConvertedName); |
| 1190 return Pair.second; |
1163 } | 1191 } |
| 1192 |
| 1193 void ReportDuplicateName(const char *NameCat, StringType &Name); |
1164 }; | 1194 }; |
1165 | 1195 |
| 1196 void ValuesymtabParser::reportUnableToAssign(const char *Context, |
| 1197 NaClBcIndexSize_t Index, |
| 1198 StringType &Name) { |
| 1199 std::string Buffer; |
| 1200 raw_string_ostream StrBuf(Buffer); |
| 1201 StrBuf << getTableKind() << " " << getBlockName() << ": " << Context |
| 1202 << " name '" << Name << "' can't be associated with index " << Index; |
| 1203 Error(StrBuf.str()); |
| 1204 } |
| 1205 |
| 1206 void ValuesymtabParser::ReportDuplicateName(const char *NameCat, |
| 1207 StringType &Name) { |
| 1208 std::string Buffer; |
| 1209 raw_string_ostream StrBuf(Buffer); |
| 1210 StrBuf << getTableKind() << " " << getBlockName() << " defines duplicate " |
| 1211 << NameCat << " name: '" << Name << "'"; |
| 1212 Error(StrBuf.str()); |
| 1213 } |
| 1214 |
1166 void ValuesymtabParser::ProcessRecord() { | 1215 void ValuesymtabParser::ProcessRecord() { |
1167 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); | 1216 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
1168 StringType ConvertedName; | 1217 StringType ConvertedName; |
1169 switch (Record.GetCode()) { | 1218 switch (Record.GetCode()) { |
1170 case naclbitc::VST_CODE_ENTRY: { | 1219 case naclbitc::VST_CODE_ENTRY: { |
1171 // VST_ENTRY: [ValueId, namechar x N] | 1220 // VST_ENTRY: [ValueId, namechar x N] |
1172 if (!isValidRecordSizeAtLeast(2, "value entry")) | 1221 if (!isValidRecordSizeAtLeast(2, "value entry")) |
1173 return; | 1222 return; |
1174 convertToString(ConvertedName); | 1223 if (convertToString(ValueNames, ConvertedName)) |
1175 setValueName(Values[0], ConvertedName); | 1224 setValueName(Values[0], ConvertedName); |
| 1225 else |
| 1226 ReportDuplicateName("value", ConvertedName); |
1176 return; | 1227 return; |
1177 } | 1228 } |
1178 case naclbitc::VST_CODE_BBENTRY: { | 1229 case naclbitc::VST_CODE_BBENTRY: { |
1179 // VST_BBENTRY: [BbId, namechar x N] | 1230 // VST_BBENTRY: [BbId, namechar x N] |
1180 if (!isValidRecordSizeAtLeast(2, "basic block entry")) | 1231 if (!isValidRecordSizeAtLeast(2, "basic block entry")) |
1181 return; | 1232 return; |
1182 convertToString(ConvertedName); | 1233 if (convertToString(BlockNames, ConvertedName)) |
1183 setBbName(Values[0], ConvertedName); | 1234 setBbName(Values[0], ConvertedName); |
| 1235 else |
| 1236 ReportDuplicateName("block", ConvertedName); |
1184 return; | 1237 return; |
1185 } | 1238 } |
1186 default: | 1239 default: |
1187 break; | 1240 break; |
1188 } | 1241 } |
1189 // If reached, don't know how to handle record. | 1242 // If reached, don't know how to handle record. |
1190 BlockParserBaseClass::ProcessRecord(); | 1243 BlockParserBaseClass::ProcessRecord(); |
1191 return; | 1244 return; |
1192 } | 1245 } |
1193 | 1246 |
(...skipping 1663 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2857 Timer(Ice::TimerStack::TT_parseFunctionValuesymtabs, | 2910 Timer(Ice::TimerStack::TT_parseFunctionValuesymtabs, |
2858 getTranslator().getContext()) {} | 2911 getTranslator().getContext()) {} |
2859 | 2912 |
2860 private: | 2913 private: |
2861 Ice::TimerMarker Timer; | 2914 Ice::TimerMarker Timer; |
2862 // Returns the enclosing function parser. | 2915 // Returns the enclosing function parser. |
2863 FunctionParser *getFunctionParser() const { | 2916 FunctionParser *getFunctionParser() const { |
2864 return reinterpret_cast<FunctionParser *>(GetEnclosingParser()); | 2917 return reinterpret_cast<FunctionParser *>(GetEnclosingParser()); |
2865 } | 2918 } |
2866 | 2919 |
2867 void setValueName(NaClBcIndexSize_t Index, StringType &Name) override; | 2920 const char *getTableKind() const final { return "Function"; } |
2868 void setBbName(NaClBcIndexSize_t Index, StringType &Name) override; | 2921 |
| 2922 void setValueName(NaClBcIndexSize_t Index, StringType &Name) final; |
| 2923 void setBbName(NaClBcIndexSize_t Index, StringType &Name) final; |
2869 | 2924 |
2870 // Reports that the assignment of Name to the value associated with index is | 2925 // Reports that the assignment of Name to the value associated with index is |
2871 // not possible, for the given Context. | 2926 // not possible, for the given Context. |
2872 void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index, | 2927 void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index, |
2873 StringType &Name) { | 2928 StringType &Name) { |
2874 std::string Buffer; | 2929 std::string Buffer; |
2875 raw_string_ostream StrBuf(Buffer); | 2930 raw_string_ostream StrBuf(Buffer); |
2876 StrBuf << "Function-local " << Context << " name '" << Name | 2931 StrBuf << "Function-local " << Context << " name '" << Name |
2877 << "' can't be associated with index " << Index; | 2932 << "' can't be associated with index " << Index; |
2878 Error(StrBuf.str()); | 2933 Error(StrBuf.str()); |
2879 } | 2934 } |
2880 }; | 2935 }; |
2881 | 2936 |
2882 void FunctionValuesymtabParser::setValueName(NaClBcIndexSize_t Index, | 2937 void FunctionValuesymtabParser::setValueName(NaClBcIndexSize_t Index, |
2883 StringType &Name) { | 2938 StringType &Name) { |
2884 // Note: We check when Index is too small, so that we can error recover | 2939 // Note: We check when Index is too small, so that we can error recover |
2885 // (FP->getOperand will create fatal error). | 2940 // (FP->getOperand will create fatal error). |
2886 if (Index < getFunctionParser()->getNumGlobalIDs()) { | 2941 if (Index < getFunctionParser()->getNumGlobalIDs()) { |
2887 reportUnableToAssign("instruction", Index, Name); | 2942 reportUnableToAssign("Global value", Index, Name); |
2888 return; | 2943 return; |
2889 } | 2944 } |
2890 if (isIRGenerationDisabled()) | 2945 if (isIRGenerationDisabled()) |
2891 return; | 2946 return; |
2892 Ice::Operand *Op = getFunctionParser()->getOperand(Index); | 2947 Ice::Operand *Op = getFunctionParser()->getOperand(Index); |
2893 if (Ice::Variable *V = dyn_cast<Ice::Variable>(Op)) { | 2948 if (Ice::Variable *V = dyn_cast<Ice::Variable>(Op)) { |
2894 if (Ice::BuildDefs::dump()) { | 2949 if (Ice::BuildDefs::dump()) { |
2895 std::string Nm(Name.data(), Name.size()); | 2950 std::string Nm(Name.data(), Name.size()); |
2896 V->setName(getFunctionParser()->getFunc(), Nm); | 2951 V->setName(getFunctionParser()->getFunc(), Nm); |
2897 } | 2952 } |
2898 } else { | 2953 } else { |
2899 reportUnableToAssign("variable", Index, Name); | 2954 reportUnableToAssign("Local value", Index, Name); |
2900 } | 2955 } |
2901 } | 2956 } |
2902 | 2957 |
2903 void FunctionValuesymtabParser::setBbName(NaClBcIndexSize_t Index, | 2958 void FunctionValuesymtabParser::setBbName(NaClBcIndexSize_t Index, |
2904 StringType &Name) { | 2959 StringType &Name) { |
2905 if (!Ice::BuildDefs::dump()) | 2960 if (!Ice::BuildDefs::dump()) |
2906 return; | 2961 return; |
2907 if (isIRGenerationDisabled()) | 2962 if (isIRGenerationDisabled()) |
2908 return; | 2963 return; |
2909 if (Index >= getFunctionParser()->getFunc()->getNumNodes()) { | 2964 if (Index >= getFunctionParser()->getFunc()->getNumNodes()) { |
2910 reportUnableToAssign("block", Index, Name); | 2965 reportUnableToAssign("Basic block", Index, Name); |
2911 return; | 2966 return; |
2912 } | 2967 } |
2913 std::string Nm(Name.data(), Name.size()); | 2968 std::string Nm(Name.data(), Name.size()); |
2914 if (Ice::BuildDefs::dump()) | 2969 if (Ice::BuildDefs::dump()) |
2915 getFunctionParser()->getFunc()->getNodes()[Index]->setName(Nm); | 2970 getFunctionParser()->getFunc()->getNodes()[Index]->setName(Nm); |
2916 } | 2971 } |
2917 | 2972 |
2918 bool FunctionParser::ParseBlock(unsigned BlockID) { | 2973 bool FunctionParser::ParseBlock(unsigned BlockID) { |
2919 switch (BlockID) { | 2974 switch (BlockID) { |
2920 case naclbitc::CONSTANTS_BLOCK_ID: { | 2975 case naclbitc::CONSTANTS_BLOCK_ID: { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2983 public: | 3038 public: |
2984 ModuleValuesymtabParser(unsigned BlockID, ModuleParser *MP) | 3039 ModuleValuesymtabParser(unsigned BlockID, ModuleParser *MP) |
2985 : ValuesymtabParser(BlockID, MP), | 3040 : ValuesymtabParser(BlockID, MP), |
2986 Timer(Ice::TimerStack::TT_parseModuleValuesymtabs, | 3041 Timer(Ice::TimerStack::TT_parseModuleValuesymtabs, |
2987 getTranslator().getContext()) {} | 3042 getTranslator().getContext()) {} |
2988 | 3043 |
2989 ~ModuleValuesymtabParser() override = default; | 3044 ~ModuleValuesymtabParser() override = default; |
2990 | 3045 |
2991 private: | 3046 private: |
2992 Ice::TimerMarker Timer; | 3047 Ice::TimerMarker Timer; |
2993 void setValueName(NaClBcIndexSize_t Index, StringType &Name) override; | 3048 const char *getTableKind() const final { return "Module"; } |
2994 void setBbName(NaClBcIndexSize_t Index, StringType &Name) override; | 3049 void setValueName(NaClBcIndexSize_t Index, StringType &Name) final; |
| 3050 void setBbName(NaClBcIndexSize_t Index, StringType &Name) final; |
2995 }; | 3051 }; |
2996 | 3052 |
2997 void ModuleValuesymtabParser::setValueName(NaClBcIndexSize_t Index, | 3053 void ModuleValuesymtabParser::setValueName(NaClBcIndexSize_t Index, |
2998 StringType &Name) { | 3054 StringType &Name) { |
2999 Context->getGlobalDeclarationByID(Index) | 3055 Context->getGlobalDeclarationByID(Index) |
3000 ->setName(StringRef(Name.data(), Name.size())); | 3056 ->setName(StringRef(Name.data(), Name.size())); |
3001 } | 3057 } |
3002 | 3058 |
3003 void ModuleValuesymtabParser::setBbName(NaClBcIndexSize_t Index, | 3059 void ModuleValuesymtabParser::setBbName(NaClBcIndexSize_t Index, |
3004 StringType &Name) { | 3060 StringType &Name) { |
3005 std::string Buffer; | 3061 reportUnableToAssign("Basic block", Index, Name); |
3006 raw_string_ostream StrBuf(Buffer); | |
3007 StrBuf << "Can't define basic block name at global level: '" << Name | |
3008 << "' -> " << Index; | |
3009 Error(StrBuf.str()); | |
3010 } | 3062 } |
3011 | 3063 |
3012 bool ModuleParser::ParseBlock(unsigned BlockID) { | 3064 bool ModuleParser::ParseBlock(unsigned BlockID) { |
3013 switch (BlockID) { | 3065 switch (BlockID) { |
3014 case naclbitc::BLOCKINFO_BLOCK_ID: | 3066 case naclbitc::BLOCKINFO_BLOCK_ID: |
3015 return NaClBitcodeParser::ParseBlock(BlockID); | 3067 return NaClBitcodeParser::ParseBlock(BlockID); |
3016 case naclbitc::TYPE_BLOCK_ID_NEW: { | 3068 case naclbitc::TYPE_BLOCK_ID_NEW: { |
3017 TypesParser Parser(BlockID, this); | 3069 TypesParser Parser(BlockID, this); |
3018 return Parser.ParseThisBlock(); | 3070 return Parser.ParseThisBlock(); |
3019 } | 3071 } |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3151 } | 3203 } |
3152 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { | 3204 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { |
3153 ErrStream | 3205 ErrStream |
3154 << IRFilename | 3206 << IRFilename |
3155 << ": Bitcode stream should be a multiple of 4 bytes in length.\n"; | 3207 << ": Bitcode stream should be a multiple of 4 bytes in length.\n"; |
3156 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); | 3208 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); |
3157 } | 3209 } |
3158 } | 3210 } |
3159 | 3211 |
3160 } // end of namespace Ice | 3212 } // end of namespace Ice |
OLD | NEW |