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 // This file implements the PNaCl bitcode file to Ice, to machine code | 10 // This file implements the PNaCl bitcode file to Ice, to machine code |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 Module *getModule() const { return Mod.get(); } | 194 Module *getModule() const { return Mod.get(); } |
195 | 195 |
196 const DataLayout &getDataLayout() const { return DL; } | 196 const DataLayout &getDataLayout() const { return DL; } |
197 | 197 |
198 /// Returns the number of bytes in the bitcode header. | 198 /// Returns the number of bytes in the bitcode header. |
199 size_t getHeaderSize() const { return Header.getHeaderSize(); } | 199 size_t getHeaderSize() const { return Header.getHeaderSize(); } |
200 | 200 |
201 /// Changes the size of the type list to the given size. | 201 /// Changes the size of the type list to the given size. |
202 void resizeTypeIDValues(unsigned NewSize) { TypeIDValues.resize(NewSize); } | 202 void resizeTypeIDValues(unsigned NewSize) { TypeIDValues.resize(NewSize); } |
203 | 203 |
| 204 /// Returns true if generation of Subzero IR is disabled. |
| 205 bool isIRGenerationDisabled() const { |
| 206 return ALLOW_DISABLE_IR_GEN ? Translator.getFlags().DisableIRGeneration |
| 207 : false; |
| 208 } |
| 209 |
204 /// Returns the undefined type associated with type ID. | 210 /// Returns the undefined type associated with type ID. |
205 /// Note: Returns extended type ready to be defined. | 211 /// Note: Returns extended type ready to be defined. |
206 ExtendedType *getTypeByIDForDefining(unsigned ID) { | 212 ExtendedType *getTypeByIDForDefining(unsigned ID) { |
207 // Get corresponding element, verifying the value is still undefined | 213 // Get corresponding element, verifying the value is still undefined |
208 // (and hence allowed to be defined). | 214 // (and hence allowed to be defined). |
209 ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Undefined); | 215 ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Undefined); |
210 if (Ty) | 216 if (Ty) |
211 return Ty; | 217 return Ty; |
212 if (ID >= TypeIDValues.size()) | 218 if (ID >= TypeIDValues.size()) |
213 TypeIDValues.resize(ID+1); | 219 TypeIDValues.resize(ID+1); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 FunctionDeclarationList.size() + VariableDeclarations.size(); | 283 FunctionDeclarationList.size() + VariableDeclarations.size(); |
278 if (ID >= ExpectedSize) | 284 if (ID >= ExpectedSize) |
279 ExpectedSize = ID; | 285 ExpectedSize = ID; |
280 ValueIDConstants.resize(ExpectedSize); | 286 ValueIDConstants.resize(ExpectedSize); |
281 } else { | 287 } else { |
282 C = ValueIDConstants[ID]; | 288 C = ValueIDConstants[ID]; |
283 } | 289 } |
284 if (C != nullptr) | 290 if (C != nullptr) |
285 return C; | 291 return C; |
286 | 292 |
| 293 if (isIRGenerationDisabled()) { |
| 294 ValueIDConstants[ID] = nullptr; |
| 295 return nullptr; |
| 296 } |
| 297 |
287 // If reached, no such constant exists, create one. | 298 // If reached, no such constant exists, create one. |
288 // TODO(kschimpf) Don't get addresses of intrinsic function declarations. | 299 // TODO(kschimpf) Don't get addresses of intrinsic function declarations. |
289 Ice::GlobalDeclaration *Decl = nullptr; | 300 Ice::GlobalDeclaration *Decl = nullptr; |
290 unsigned FcnIDSize = FunctionDeclarationList.size(); | 301 unsigned FcnIDSize = FunctionDeclarationList.size(); |
291 if (ID < FcnIDSize) { | 302 if (ID < FcnIDSize) { |
292 Decl = FunctionDeclarationList[ID]; | 303 Decl = FunctionDeclarationList[ID]; |
293 } else if ((ID - FcnIDSize) < VariableDeclarations.size()) { | 304 } else if ((ID - FcnIDSize) < VariableDeclarations.size()) { |
294 Decl = VariableDeclarations[ID - FcnIDSize]; | 305 Decl = VariableDeclarations[ID - FcnIDSize]; |
295 } | 306 } |
296 std::string Name; | 307 std::string Name; |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
516 // Constructor for nested block parsers. | 527 // Constructor for nested block parsers. |
517 BlockParserBaseClass(unsigned BlockID, BlockParserBaseClass *EnclosingParser) | 528 BlockParserBaseClass(unsigned BlockID, BlockParserBaseClass *EnclosingParser) |
518 : NaClBitcodeParser(BlockID, EnclosingParser), | 529 : NaClBitcodeParser(BlockID, EnclosingParser), |
519 Context(EnclosingParser->Context) {} | 530 Context(EnclosingParser->Context) {} |
520 | 531 |
521 // Gets the translator associated with the bitcode parser. | 532 // Gets the translator associated with the bitcode parser. |
522 Ice::Translator &getTranslator() const { return Context->getTranslator(); } | 533 Ice::Translator &getTranslator() const { return Context->getTranslator(); } |
523 | 534 |
524 const Ice::ClFlags &getFlags() const { return getTranslator().getFlags(); } | 535 const Ice::ClFlags &getFlags() const { return getTranslator().getFlags(); } |
525 | 536 |
| 537 bool isIRGenerationDisabled() const { |
| 538 return ALLOW_DISABLE_IR_GEN ? getTranslator().getFlags().DisableIRGeneration |
| 539 : false; |
| 540 } |
| 541 |
526 // Generates an error Message with the bit address prefixed to it. | 542 // Generates an error Message with the bit address prefixed to it. |
527 bool Error(const std::string &Message) override { | 543 bool Error(const std::string &Message) override { |
528 uint64_t Bit = Record.GetStartBit() + Context->getHeaderSize() * 8; | 544 uint64_t Bit = Record.GetStartBit() + Context->getHeaderSize() * 8; |
529 std::string Buffer; | 545 std::string Buffer; |
530 raw_string_ostream StrBuf(Buffer); | 546 raw_string_ostream StrBuf(Buffer); |
531 StrBuf << "(" << format("%" PRIu64 ":%u", (Bit / 8), | 547 StrBuf << "(" << format("%" PRIu64 ":%u", (Bit / 8), |
532 static_cast<unsigned>(Bit % 8)) << ") " << Message; | 548 static_cast<unsigned>(Bit % 8)) << ") " << Message; |
533 return Context->Error(StrBuf.str()); | 549 return Context->Error(StrBuf.str()); |
534 } | 550 } |
535 | 551 |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
804 class GlobalsParser : public BlockParserBaseClass { | 820 class GlobalsParser : public BlockParserBaseClass { |
805 public: | 821 public: |
806 GlobalsParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) | 822 GlobalsParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) |
807 : BlockParserBaseClass(BlockID, EnclosingParser), | 823 : BlockParserBaseClass(BlockID, EnclosingParser), |
808 Timer(Ice::TimerStack::TT_parseGlobals, getTranslator().getContext()), | 824 Timer(Ice::TimerStack::TT_parseGlobals, getTranslator().getContext()), |
809 InitializersNeeded(0), NextGlobalID(0), | 825 InitializersNeeded(0), NextGlobalID(0), |
810 DummyGlobalVar( | 826 DummyGlobalVar( |
811 Ice::VariableDeclaration::create(getTranslator().getContext())), | 827 Ice::VariableDeclaration::create(getTranslator().getContext())), |
812 CurGlobalVar(DummyGlobalVar) {} | 828 CurGlobalVar(DummyGlobalVar) {} |
813 | 829 |
| 830 ~GlobalsParser() final {} |
| 831 |
814 private: | 832 private: |
815 Ice::TimerMarker Timer; | 833 Ice::TimerMarker Timer; |
816 // Keeps track of how many initializers are expected for the global variable | 834 // Keeps track of how many initializers are expected for the global variable |
817 // declaration being built. | 835 // declaration being built. |
818 unsigned InitializersNeeded; | 836 unsigned InitializersNeeded; |
819 | 837 |
820 // The index of the next global variable declaration. | 838 // The index of the next global variable declaration. |
821 unsigned NextGlobalID; | 839 unsigned NextGlobalID; |
822 | 840 |
823 // Dummy global variable declaration to guarantee CurGlobalVar is | 841 // Dummy global variable declaration to guarantee CurGlobalVar is |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
874 Error("Globals count record not first in block."); | 892 Error("Globals count record not first in block."); |
875 return; | 893 return; |
876 } | 894 } |
877 Context->CreateGlobalVariables(Values[0]); | 895 Context->CreateGlobalVariables(Values[0]); |
878 return; | 896 return; |
879 case naclbitc::GLOBALVAR_VAR: { | 897 case naclbitc::GLOBALVAR_VAR: { |
880 // VAR: [align, isconst] | 898 // VAR: [align, isconst] |
881 if (!isValidRecordSize(2, "Globals variable")) | 899 if (!isValidRecordSize(2, "Globals variable")) |
882 return; | 900 return; |
883 verifyNoMissingInitializers(); | 901 verifyNoMissingInitializers(); |
884 InitializersNeeded = 1; | 902 if (!isIRGenerationDisabled()) { |
885 CurGlobalVar = Context->getGlobalVariableByID(NextGlobalID); | 903 InitializersNeeded = 1; |
886 CurGlobalVar->setAlignment((1 << Values[0]) >> 1); | 904 CurGlobalVar = Context->getGlobalVariableByID(NextGlobalID); |
887 CurGlobalVar->setIsConstant(Values[1] != 0); | 905 CurGlobalVar->setAlignment((1 << Values[0]) >> 1); |
| 906 CurGlobalVar->setIsConstant(Values[1] != 0); |
| 907 } |
888 ++NextGlobalID; | 908 ++NextGlobalID; |
889 return; | 909 return; |
890 } | 910 } |
891 case naclbitc::GLOBALVAR_COMPOUND: | 911 case naclbitc::GLOBALVAR_COMPOUND: |
892 // COMPOUND: [size] | 912 // COMPOUND: [size] |
893 if (!isValidRecordSize(1, "globals compound")) | 913 if (!isValidRecordSize(1, "globals compound")) |
894 return; | 914 return; |
895 if (!CurGlobalVar->getInitializers().empty()) { | 915 if (!CurGlobalVar->getInitializers().empty()) { |
896 Error("Globals compound record not first initializer"); | 916 Error("Globals compound record not first initializer"); |
897 return; | 917 return; |
898 } | 918 } |
899 if (Values[0] < 2) { | 919 if (Values[0] < 2) { |
900 std::string Buffer; | 920 std::string Buffer; |
901 raw_string_ostream StrBuf(Buffer); | 921 raw_string_ostream StrBuf(Buffer); |
902 StrBuf << "Globals compound record size invalid. Found: " << Values[0]; | 922 StrBuf << "Globals compound record size invalid. Found: " << Values[0]; |
903 Error(StrBuf.str()); | 923 Error(StrBuf.str()); |
904 return; | 924 return; |
905 } | 925 } |
| 926 if (isIRGenerationDisabled()) |
| 927 return; |
906 InitializersNeeded = Values[0]; | 928 InitializersNeeded = Values[0]; |
907 return; | 929 return; |
908 case naclbitc::GLOBALVAR_ZEROFILL: { | 930 case naclbitc::GLOBALVAR_ZEROFILL: { |
909 // ZEROFILL: [size] | 931 // ZEROFILL: [size] |
910 if (!isValidRecordSize(1, "Globals zerofill")) | 932 if (!isValidRecordSize(1, "Globals zerofill")) |
911 return; | 933 return; |
| 934 if (isIRGenerationDisabled()) |
| 935 return; |
912 CurGlobalVar->addInitializer( | 936 CurGlobalVar->addInitializer( |
913 new Ice::VariableDeclaration::ZeroInitializer(Values[0])); | 937 new Ice::VariableDeclaration::ZeroInitializer(Values[0])); |
914 return; | 938 return; |
915 } | 939 } |
916 case naclbitc::GLOBALVAR_DATA: { | 940 case naclbitc::GLOBALVAR_DATA: { |
917 // DATA: [b0, b1, ...] | 941 // DATA: [b0, b1, ...] |
918 if (!isValidRecordSizeAtLeast(1, "Globals data")) | 942 if (!isValidRecordSizeAtLeast(1, "Globals data")) |
919 return; | 943 return; |
| 944 if (isIRGenerationDisabled()) |
| 945 return; |
920 CurGlobalVar->addInitializer( | 946 CurGlobalVar->addInitializer( |
921 new Ice::VariableDeclaration::DataInitializer(Values)); | 947 new Ice::VariableDeclaration::DataInitializer(Values)); |
922 return; | 948 return; |
923 } | 949 } |
924 case naclbitc::GLOBALVAR_RELOC: { | 950 case naclbitc::GLOBALVAR_RELOC: { |
925 // RELOC: [val, [addend]] | 951 // RELOC: [val, [addend]] |
926 if (!isValidRecordSizeInRange(1, 2, "Globals reloc")) | 952 if (!isValidRecordSizeInRange(1, 2, "Globals reloc")) |
927 return; | 953 return; |
| 954 if (isIRGenerationDisabled()) |
| 955 return; |
928 unsigned Index = Values[0]; | 956 unsigned Index = Values[0]; |
929 Ice::SizeT Offset = 0; | 957 Ice::SizeT Offset = 0; |
930 if (Values.size() == 2) | 958 if (Values.size() == 2) |
931 Offset = Values[1]; | 959 Offset = Values[1]; |
932 CurGlobalVar->addInitializer(new Ice::VariableDeclaration::RelocInitializer( | 960 CurGlobalVar->addInitializer(new Ice::VariableDeclaration::RelocInitializer( |
933 Context->getGlobalDeclarationByID(Index), Offset)); | 961 Context->getGlobalDeclarationByID(Index), Offset)); |
934 return; | 962 return; |
935 } | 963 } |
936 default: | 964 default: |
937 BlockParserBaseClass::ProcessRecord(); | 965 BlockParserBaseClass::ProcessRecord(); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1004 /// Parses function blocks in the bitcode file. | 1032 /// Parses function blocks in the bitcode file. |
1005 class FunctionParser : public BlockParserBaseClass { | 1033 class FunctionParser : public BlockParserBaseClass { |
1006 FunctionParser(const FunctionParser &) = delete; | 1034 FunctionParser(const FunctionParser &) = delete; |
1007 FunctionParser &operator=(const FunctionParser &) = delete; | 1035 FunctionParser &operator=(const FunctionParser &) = delete; |
1008 friend class FunctionValuesymtabParser; | 1036 friend class FunctionValuesymtabParser; |
1009 | 1037 |
1010 public: | 1038 public: |
1011 FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) | 1039 FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) |
1012 : BlockParserBaseClass(BlockID, EnclosingParser), | 1040 : BlockParserBaseClass(BlockID, EnclosingParser), |
1013 Timer(Ice::TimerStack::TT_parseFunctions, getTranslator().getContext()), | 1041 Timer(Ice::TimerStack::TT_parseFunctions, getTranslator().getContext()), |
1014 Func(new Ice::Cfg(getTranslator().getContext())), CurrentBbIndex(0), | 1042 Func(isIRGenerationDisabled() |
1015 FcnId(Context->getNextFunctionBlockValueID()), | 1043 ? nullptr |
| 1044 : new Ice::Cfg(getTranslator().getContext())), |
| 1045 CurrentBbIndex(0), FcnId(Context->getNextFunctionBlockValueID()), |
1016 FuncDecl(Context->getFunctionByID(FcnId)), | 1046 FuncDecl(Context->getFunctionByID(FcnId)), |
1017 CachedNumGlobalValueIDs(Context->getNumGlobalIDs()), | 1047 CachedNumGlobalValueIDs(Context->getNumGlobalIDs()), |
1018 NextLocalInstIndex(Context->getNumGlobalIDs()), | 1048 NextLocalInstIndex(Context->getNumGlobalIDs()), |
1019 InstIsTerminating(false) { | 1049 InstIsTerminating(false) { |
1020 Func->setFunctionName(FuncDecl->getName()); | |
1021 if (getFlags().TimeEachFunction) | 1050 if (getFlags().TimeEachFunction) |
1022 getTranslator().getContext()->pushTimer( | 1051 getTranslator().getContext()->pushTimer( |
1023 getTranslator().getContext()->getTimerID( | 1052 getTranslator().getContext()->getTimerID( |
1024 Ice::GlobalContext::TSK_Funcs, Func->getFunctionName()), | 1053 Ice::GlobalContext::TSK_Funcs, FuncDecl->getName()), |
1025 Ice::GlobalContext::TSK_Funcs); | 1054 Ice::GlobalContext::TSK_Funcs); |
1026 // TODO(kschimpf) Clean up API to add a function signature to | 1055 // TODO(kschimpf) Clean up API to add a function signature to |
1027 // a CFG. | 1056 // a CFG. |
1028 const Ice::FuncSigType &Signature = FuncDecl->getSignature(); | 1057 const Ice::FuncSigType &Signature = FuncDecl->getSignature(); |
1029 Func->setReturnType(Signature.getReturnType()); | 1058 if (isIRGenerationDisabled()) { |
1030 Func->setInternal(FuncDecl->getLinkage() == GlobalValue::InternalLinkage); | 1059 CurrentNode = nullptr; |
1031 CurrentNode = InstallNextBasicBlock(); | 1060 for (Ice::Type ArgType : Signature.getArgList()) { |
1032 Func->setEntryNode(CurrentNode); | 1061 (void)ArgType; |
1033 for (Ice::Type ArgType : Signature.getArgList()) { | 1062 setNextLocalInstIndex(nullptr); |
1034 Func->addArg(getNextInstVar(ArgType)); | 1063 } |
| 1064 } else { |
| 1065 Func->setFunctionName(FuncDecl->getName()); |
| 1066 Func->setReturnType(Signature.getReturnType()); |
| 1067 Func->setInternal(FuncDecl->getLinkage() == GlobalValue::InternalLinkage); |
| 1068 CurrentNode = InstallNextBasicBlock(); |
| 1069 Func->setEntryNode(CurrentNode); |
| 1070 for (Ice::Type ArgType : Signature.getArgList()) { |
| 1071 Func->addArg(getNextInstVar(ArgType)); |
| 1072 } |
1035 } | 1073 } |
1036 } | 1074 } |
1037 | 1075 |
1038 ~FunctionParser() override {}; | 1076 ~FunctionParser() final {} |
| 1077 |
| 1078 void setNextLocalInstIndex(Ice::Operand *Op) { |
| 1079 setOperand(NextLocalInstIndex++, Op); |
| 1080 } |
1039 | 1081 |
1040 // Set the next constant ID to the given constant C. | 1082 // Set the next constant ID to the given constant C. |
1041 void setNextConstantID(Ice::Constant *C) { | 1083 void setNextConstantID(Ice::Constant *C) { setNextLocalInstIndex(C); } |
1042 setOperand(NextLocalInstIndex++, C); | |
1043 } | |
1044 | 1084 |
1045 private: | 1085 private: |
1046 Ice::TimerMarker Timer; | 1086 Ice::TimerMarker Timer; |
1047 // The corresponding ICE function defined by the function block. | 1087 // The corresponding ICE function defined by the function block. |
1048 Ice::Cfg *Func; | 1088 Ice::Cfg *Func; |
1049 // The index to the current basic block being built. | 1089 // The index to the current basic block being built. |
1050 uint32_t CurrentBbIndex; | 1090 uint32_t CurrentBbIndex; |
1051 // The basic block being built. | 1091 // The basic block being built. |
1052 Ice::CfgNode *CurrentNode; | 1092 Ice::CfgNode *CurrentNode; |
1053 // The ID for the function. | 1093 // The ID for the function. |
1054 unsigned FcnId; | 1094 unsigned FcnId; |
1055 // The corresponding function declaration. | 1095 // The corresponding function declaration. |
1056 Ice::FunctionDeclaration *FuncDecl; | 1096 Ice::FunctionDeclaration *FuncDecl; |
1057 // Holds the dividing point between local and global absolute value indices. | 1097 // Holds the dividing point between local and global absolute value indices. |
1058 uint32_t CachedNumGlobalValueIDs; | 1098 uint32_t CachedNumGlobalValueIDs; |
1059 // Holds operands local to the function block, based on indices | 1099 // Holds operands local to the function block, based on indices |
1060 // defined in the bitcode file. | 1100 // defined in the bitcode file. |
1061 std::vector<Ice::Operand *> LocalOperands; | 1101 std::vector<Ice::Operand *> LocalOperands; |
1062 // Holds the index within LocalOperands corresponding to the next | 1102 // Holds the index within LocalOperands corresponding to the next |
1063 // instruction that generates a value. | 1103 // instruction that generates a value. |
1064 uint32_t NextLocalInstIndex; | 1104 uint32_t NextLocalInstIndex; |
1065 // True if the last processed instruction was a terminating | 1105 // True if the last processed instruction was a terminating |
1066 // instruction. | 1106 // instruction. |
1067 bool InstIsTerminating; | 1107 bool InstIsTerminating; |
1068 // Upper limit of alignment power allowed by LLVM | 1108 // Upper limit of alignment power allowed by LLVM |
1069 static const uint64_t AlignPowerLimit = 29; | 1109 static const uint64_t AlignPowerLimit = 29; |
1070 | 1110 |
| 1111 void popTimerIfTimingEachFunction() const { |
| 1112 if (getFlags().TimeEachFunction) { |
| 1113 getTranslator().getContext()->popTimer( |
| 1114 getTranslator().getContext()->getTimerID( |
| 1115 Ice::GlobalContext::TSK_Funcs, Func->getFunctionName()), |
| 1116 Ice::GlobalContext::TSK_Funcs); |
| 1117 } |
| 1118 } |
| 1119 |
1071 // Extracts the corresponding Alignment to use, given the AlignPower | 1120 // Extracts the corresponding Alignment to use, given the AlignPower |
1072 // (i.e. 2**AlignPower, or 0 if AlignPower == 0). InstName is the | 1121 // (i.e. 2**AlignPower, or 0 if AlignPower == 0). InstName is the |
1073 // name of the instruction the alignment appears in. | 1122 // name of the instruction the alignment appears in. |
1074 void extractAlignment(const char *InstName, uint64_t AlignPower, | 1123 void extractAlignment(const char *InstName, uint64_t AlignPower, |
1075 unsigned &Alignment) { | 1124 unsigned &Alignment) { |
1076 if (AlignPower <= AlignPowerLimit) { | 1125 if (AlignPower <= AlignPowerLimit) { |
1077 Alignment = (1 << static_cast<unsigned>(AlignPower)) >> 1; | 1126 Alignment = (1 << static_cast<unsigned>(AlignPower)) >> 1; |
1078 return; | 1127 return; |
1079 } | 1128 } |
1080 std::string Buffer; | 1129 std::string Buffer; |
1081 raw_string_ostream StrBuf(Buffer); | 1130 raw_string_ostream StrBuf(Buffer); |
1082 StrBuf << InstName << " alignment greater than 2**" << AlignPowerLimit | 1131 StrBuf << InstName << " alignment greater than 2**" << AlignPowerLimit |
1083 << ". Found: 2**" << AlignPower; | 1132 << ". Found: 2**" << AlignPower; |
1084 Error(StrBuf.str()); | 1133 Error(StrBuf.str()); |
1085 // Error recover with value that is always acceptable. | 1134 // Error recover with value that is always acceptable. |
1086 Alignment = 1; | 1135 Alignment = 1; |
1087 } | 1136 } |
1088 | 1137 |
1089 bool ParseBlock(unsigned BlockID) override; | 1138 bool ParseBlock(unsigned BlockID) override; |
1090 | 1139 |
1091 void ProcessRecord() override; | 1140 void ProcessRecord() override; |
1092 | 1141 |
1093 void ExitBlock() override; | 1142 void ExitBlock() override; |
1094 | 1143 |
1095 // Creates and appends a new basic block to the list of basic blocks. | 1144 // Creates and appends a new basic block to the list of basic blocks. |
1096 Ice::CfgNode *InstallNextBasicBlock() { return Func->makeNode(); } | 1145 Ice::CfgNode *InstallNextBasicBlock() { |
| 1146 assert(!isIRGenerationDisabled()); |
| 1147 return Func->makeNode(); |
| 1148 } |
1097 | 1149 |
1098 // Returns the Index-th basic block in the list of basic blocks. | 1150 // Returns the Index-th basic block in the list of basic blocks. |
1099 Ice::CfgNode *getBasicBlock(uint32_t Index) { | 1151 Ice::CfgNode *getBasicBlock(uint32_t Index) { |
| 1152 assert(!isIRGenerationDisabled()); |
1100 const Ice::NodeList &Nodes = Func->getNodes(); | 1153 const Ice::NodeList &Nodes = Func->getNodes(); |
1101 if (Index >= Nodes.size()) { | 1154 if (Index >= Nodes.size()) { |
1102 std::string Buffer; | 1155 std::string Buffer; |
1103 raw_string_ostream StrBuf(Buffer); | 1156 raw_string_ostream StrBuf(Buffer); |
1104 StrBuf << "Reference to basic block " << Index | 1157 StrBuf << "Reference to basic block " << Index |
1105 << " not found. Must be less than " << Nodes.size(); | 1158 << " not found. Must be less than " << Nodes.size(); |
1106 Error(StrBuf.str()); | 1159 Error(StrBuf.str()); |
1107 // TODO(kschimpf) Remove error recovery once implementation complete. | 1160 // TODO(kschimpf) Remove error recovery once implementation complete. |
1108 Index = 0; | 1161 Index = 0; |
1109 } | 1162 } |
1110 return Nodes[Index]; | 1163 return Nodes[Index]; |
1111 } | 1164 } |
1112 | 1165 |
1113 // Returns the Index-th basic block in the list of basic blocks. | 1166 // Returns the Index-th basic block in the list of basic blocks. |
1114 // Assumes Index corresponds to a branch instruction. Hence, if | 1167 // Assumes Index corresponds to a branch instruction. Hence, if |
1115 // the branch references the entry block, it also generates a | 1168 // the branch references the entry block, it also generates a |
1116 // corresponding error. | 1169 // corresponding error. |
1117 Ice::CfgNode *getBranchBasicBlock(uint32_t Index) { | 1170 Ice::CfgNode *getBranchBasicBlock(uint32_t Index) { |
| 1171 assert(!isIRGenerationDisabled()); |
1118 if (Index == 0) { | 1172 if (Index == 0) { |
1119 Error("Branch to entry block not allowed"); | 1173 Error("Branch to entry block not allowed"); |
1120 // TODO(kschimpf) Remove error recovery once implementation complete. | 1174 // TODO(kschimpf) Remove error recovery once implementation complete. |
1121 } | 1175 } |
1122 return getBasicBlock(Index); | 1176 return getBasicBlock(Index); |
1123 } | 1177 } |
1124 | 1178 |
1125 // Generate an instruction variable with type Ty. | 1179 // Generate an instruction variable with type Ty. |
1126 Ice::Variable *createInstVar(Ice::Type Ty) { | 1180 Ice::Variable *createInstVar(Ice::Type Ty) { |
| 1181 assert(!isIRGenerationDisabled()); |
1127 if (Ty == Ice::IceType_void) { | 1182 if (Ty == Ice::IceType_void) { |
1128 Error("Can't define instruction value using type void"); | 1183 Error("Can't define instruction value using type void"); |
1129 // Recover since we can't throw an exception. | 1184 // Recover since we can't throw an exception. |
1130 Ty = Ice::IceType_i32; | 1185 Ty = Ice::IceType_i32; |
1131 } | 1186 } |
1132 return Func->makeVariable(Ty); | 1187 return Func->makeVariable(Ty); |
1133 } | 1188 } |
1134 | 1189 |
1135 // Generates the next available local variable using the given type. | 1190 // Generates the next available local variable using the given type. |
1136 Ice::Variable *getNextInstVar(Ice::Type Ty) { | 1191 Ice::Variable *getNextInstVar(Ice::Type Ty) { |
| 1192 assert(!isIRGenerationDisabled()); |
1137 assert(NextLocalInstIndex >= CachedNumGlobalValueIDs); | 1193 assert(NextLocalInstIndex >= CachedNumGlobalValueIDs); |
1138 // Before creating one, see if a forwardtyperef has already defined it. | 1194 // Before creating one, see if a forwardtyperef has already defined it. |
1139 uint32_t LocalIndex = NextLocalInstIndex - CachedNumGlobalValueIDs; | 1195 uint32_t LocalIndex = NextLocalInstIndex - CachedNumGlobalValueIDs; |
1140 if (LocalIndex < LocalOperands.size()) { | 1196 if (LocalIndex < LocalOperands.size()) { |
1141 Ice::Operand *Op = LocalOperands[LocalIndex]; | 1197 Ice::Operand *Op = LocalOperands[LocalIndex]; |
1142 if (Op != nullptr) { | 1198 if (Op != nullptr) { |
1143 if (Ice::Variable *Var = dyn_cast<Ice::Variable>(Op)) { | 1199 if (Ice::Variable *Var = dyn_cast<Ice::Variable>(Op)) { |
1144 if (Var->getType() == Ty) { | 1200 if (Var->getType() == Ty) { |
1145 ++NextLocalInstIndex; | 1201 ++NextLocalInstIndex; |
1146 return Var; | 1202 return Var; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1184 uint32_t LocalIndex = Index - CachedNumGlobalValueIDs; | 1240 uint32_t LocalIndex = Index - CachedNumGlobalValueIDs; |
1185 if (LocalIndex >= LocalOperands.size()) { | 1241 if (LocalIndex >= LocalOperands.size()) { |
1186 std::string Buffer; | 1242 std::string Buffer; |
1187 raw_string_ostream StrBuf(Buffer); | 1243 raw_string_ostream StrBuf(Buffer); |
1188 StrBuf << "Value index " << Index << " not defined!"; | 1244 StrBuf << "Value index " << Index << " not defined!"; |
1189 Error(StrBuf.str()); | 1245 Error(StrBuf.str()); |
1190 report_fatal_error("Unable to continue"); | 1246 report_fatal_error("Unable to continue"); |
1191 } | 1247 } |
1192 Ice::Operand *Op = LocalOperands[LocalIndex]; | 1248 Ice::Operand *Op = LocalOperands[LocalIndex]; |
1193 if (Op == nullptr) { | 1249 if (Op == nullptr) { |
| 1250 if (isIRGenerationDisabled()) |
| 1251 return nullptr; |
1194 std::string Buffer; | 1252 std::string Buffer; |
1195 raw_string_ostream StrBuf(Buffer); | 1253 raw_string_ostream StrBuf(Buffer); |
1196 StrBuf << "Value index " << Index << " not defined!"; | 1254 StrBuf << "Value index " << Index << " not defined!"; |
1197 Error(StrBuf.str()); | 1255 Error(StrBuf.str()); |
1198 report_fatal_error("Unable to continue"); | 1256 report_fatal_error("Unable to continue"); |
1199 } | 1257 } |
1200 return Op; | 1258 return Op; |
1201 } | 1259 } |
1202 | 1260 |
1203 // Sets element Index (in the local operands list) to Op. | 1261 // Sets element Index (in the local operands list) to Op. |
1204 void setOperand(uint32_t Index, Ice::Operand *Op) { | 1262 void setOperand(uint32_t Index, Ice::Operand *Op) { |
1205 assert(Op); | 1263 assert(Op || isIRGenerationDisabled()); |
1206 // Check if simple push works. | 1264 // Check if simple push works. |
1207 uint32_t LocalIndex = Index - CachedNumGlobalValueIDs; | 1265 uint32_t LocalIndex = Index - CachedNumGlobalValueIDs; |
1208 if (LocalIndex == LocalOperands.size()) { | 1266 if (LocalIndex == LocalOperands.size()) { |
1209 LocalOperands.push_back(Op); | 1267 LocalOperands.push_back(Op); |
1210 return; | 1268 return; |
1211 } | 1269 } |
1212 | 1270 |
1213 // Must be forward reference, expand vector to accommodate. | 1271 // Must be forward reference, expand vector to accommodate. |
1214 if (LocalIndex >= LocalOperands.size()) | 1272 if (LocalIndex >= LocalOperands.size()) |
1215 LocalOperands.resize(LocalIndex + 1); | 1273 LocalOperands.resize(LocalIndex + 1); |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1626 }; | 1684 }; |
1627 | 1685 |
1628 void FunctionParser::ReportInvalidBinopOpcode(unsigned Opcode, Ice::Type Ty) { | 1686 void FunctionParser::ReportInvalidBinopOpcode(unsigned Opcode, Ice::Type Ty) { |
1629 std::string Buffer; | 1687 std::string Buffer; |
1630 raw_string_ostream StrBuf(Buffer); | 1688 raw_string_ostream StrBuf(Buffer); |
1631 StrBuf << "Binary opcode " << Opcode << "not understood for type " << Ty; | 1689 StrBuf << "Binary opcode " << Opcode << "not understood for type " << Ty; |
1632 Error(StrBuf.str()); | 1690 Error(StrBuf.str()); |
1633 } | 1691 } |
1634 | 1692 |
1635 void FunctionParser::ExitBlock() { | 1693 void FunctionParser::ExitBlock() { |
| 1694 if (isIRGenerationDisabled()) { |
| 1695 popTimerIfTimingEachFunction(); |
| 1696 return; |
| 1697 } |
1636 // Before translating, check for blocks without instructions, and | 1698 // Before translating, check for blocks without instructions, and |
1637 // insert unreachable. This shouldn't happen, but be safe. | 1699 // insert unreachable. This shouldn't happen, but be safe. |
1638 unsigned Index = 0; | 1700 unsigned Index = 0; |
1639 for (Ice::CfgNode *Node : Func->getNodes()) { | 1701 for (Ice::CfgNode *Node : Func->getNodes()) { |
1640 if (Node->getInsts().empty()) { | 1702 if (Node->getInsts().empty()) { |
1641 std::string Buffer; | 1703 std::string Buffer; |
1642 raw_string_ostream StrBuf(Buffer); | 1704 raw_string_ostream StrBuf(Buffer); |
1643 StrBuf << "Basic block " << Index << " contains no instructions"; | 1705 StrBuf << "Basic block " << Index << " contains no instructions"; |
1644 Error(StrBuf.str()); | 1706 Error(StrBuf.str()); |
1645 // TODO(kschimpf) Remove error recovery once implementation complete. | 1707 // TODO(kschimpf) Remove error recovery once implementation complete. |
1646 Node->appendInst(Ice::InstUnreachable::create(Func)); | 1708 Node->appendInst(Ice::InstUnreachable::create(Func)); |
1647 } | 1709 } |
1648 ++Index; | 1710 ++Index; |
1649 } | 1711 } |
1650 Func->computePredecessors(); | 1712 Func->computePredecessors(); |
1651 // Note: Once any errors have been found, we turn off all | 1713 // Note: Once any errors have been found, we turn off all |
1652 // translation of all remaining functions. This allows use to see | 1714 // translation of all remaining functions. This allows use to see |
1653 // multiple errors, without adding extra checks to the translator | 1715 // multiple errors, without adding extra checks to the translator |
1654 // for such parsing errors. | 1716 // for such parsing errors. |
1655 if (Context->getNumErrors() == 0) | 1717 if (Context->getNumErrors() == 0) |
1656 getTranslator().translateFcn(Func); | 1718 getTranslator().translateFcn(Func); |
1657 if (getFlags().TimeEachFunction) | 1719 popTimerIfTimingEachFunction(); |
1658 getTranslator().getContext()->popTimer( | |
1659 getTranslator().getContext()->getTimerID(Ice::GlobalContext::TSK_Funcs, | |
1660 Func->getFunctionName()), | |
1661 Ice::GlobalContext::TSK_Funcs); | |
1662 } | 1720 } |
1663 | 1721 |
1664 void FunctionParser::ReportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, | 1722 void FunctionParser::ReportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, |
1665 Ice::Type OpTy) { | 1723 Ice::Type OpTy) { |
1666 std::string Buffer; | 1724 std::string Buffer; |
1667 raw_string_ostream StrBuf(Buffer); | 1725 raw_string_ostream StrBuf(Buffer); |
1668 StrBuf << "Invalid operator type for " << Ice::InstArithmetic::getOpName(Op) | 1726 StrBuf << "Invalid operator type for " << Ice::InstArithmetic::getOpName(Op) |
1669 << ". Found " << OpTy; | 1727 << ". Found " << OpTy; |
1670 Error(StrBuf.str()); | 1728 Error(StrBuf.str()); |
1671 } | 1729 } |
1672 | 1730 |
1673 void FunctionParser::ProcessRecord() { | 1731 void FunctionParser::ProcessRecord() { |
| 1732 // Note: To better separate parse/IR generation times, when IR generation |
| 1733 // is disabled we do the following: |
| 1734 // 1) Delay exiting until after we extract operands. |
| 1735 // 2) return before we access operands, since all operands will be a nullptr. |
1674 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); | 1736 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
1675 if (InstIsTerminating) { | 1737 if (InstIsTerminating) { |
1676 InstIsTerminating = false; | 1738 InstIsTerminating = false; |
1677 CurrentNode = getBasicBlock(++CurrentBbIndex); | 1739 if (!isIRGenerationDisabled()) |
| 1740 CurrentNode = getBasicBlock(++CurrentBbIndex); |
1678 } | 1741 } |
1679 // The base index for relative indexing. | 1742 // The base index for relative indexing. |
1680 int32_t BaseIndex = getNextInstIndex(); | 1743 int32_t BaseIndex = getNextInstIndex(); |
1681 switch (Record.GetCode()) { | 1744 switch (Record.GetCode()) { |
1682 case naclbitc::FUNC_CODE_DECLAREBLOCKS: { | 1745 case naclbitc::FUNC_CODE_DECLAREBLOCKS: { |
1683 // DECLAREBLOCKS: [n] | 1746 // DECLAREBLOCKS: [n] |
1684 if (!isValidRecordSize(1, "function block count")) | 1747 if (!isValidRecordSize(1, "function block count")) |
1685 return; | 1748 return; |
1686 if (Func->getNodes().size() != 1) { | |
1687 Error("Duplicate function block count record"); | |
1688 return; | |
1689 } | |
1690 uint32_t NumBbs = Values[0]; | 1749 uint32_t NumBbs = Values[0]; |
1691 if (NumBbs == 0) { | 1750 if (NumBbs == 0) { |
1692 Error("Functions must contain at least one basic block."); | 1751 Error("Functions must contain at least one basic block."); |
1693 // TODO(kschimpf) Remove error recovery once implementation complete. | 1752 // TODO(kschimpf) Remove error recovery once implementation complete. |
1694 NumBbs = 1; | 1753 NumBbs = 1; |
1695 } | 1754 } |
| 1755 if (isIRGenerationDisabled()) |
| 1756 return; |
| 1757 if (Func->getNodes().size() != 1) { |
| 1758 Error("Duplicate function block count record"); |
| 1759 return; |
| 1760 } |
1696 // Install the basic blocks, skipping bb0 which was created in the | 1761 // Install the basic blocks, skipping bb0 which was created in the |
1697 // constructor. | 1762 // constructor. |
1698 for (size_t i = 1; i < NumBbs; ++i) | 1763 for (size_t i = 1; i < NumBbs; ++i) |
1699 InstallNextBasicBlock(); | 1764 InstallNextBasicBlock(); |
1700 return; | 1765 return; |
1701 } | 1766 } |
1702 case naclbitc::FUNC_CODE_INST_BINOP: { | 1767 case naclbitc::FUNC_CODE_INST_BINOP: { |
1703 // BINOP: [opval, opval, opcode] | 1768 // BINOP: [opval, opval, opcode] |
1704 if (!isValidRecordSize(3, "function block binop")) | 1769 if (!isValidRecordSize(3, "function block binop")) |
1705 return; | 1770 return; |
1706 Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex); | 1771 Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex); |
1707 Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex); | 1772 Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex); |
| 1773 if (isIRGenerationDisabled()) { |
| 1774 assert(Op1 == nullptr && Op2 == nullptr); |
| 1775 setNextLocalInstIndex(nullptr); |
| 1776 return; |
| 1777 } |
1708 Ice::Type Type1 = Op1->getType(); | 1778 Ice::Type Type1 = Op1->getType(); |
1709 Ice::Type Type2 = Op2->getType(); | 1779 Ice::Type Type2 = Op2->getType(); |
1710 if (Type1 != Type2) { | 1780 if (Type1 != Type2) { |
1711 std::string Buffer; | 1781 std::string Buffer; |
1712 raw_string_ostream StrBuf(Buffer); | 1782 raw_string_ostream StrBuf(Buffer); |
1713 StrBuf << "Binop argument types differ: " << Type1 << " and " << Type2; | 1783 StrBuf << "Binop argument types differ: " << Type1 << " and " << Type2; |
1714 Error(StrBuf.str()); | 1784 Error(StrBuf.str()); |
1715 appendErrorInstruction(Type1); | 1785 appendErrorInstruction(Type1); |
1716 return; | 1786 return; |
1717 } | 1787 } |
(...skipping 15 matching lines...) Expand all Loading... |
1733 Ice::InstCast::OpKind CastKind; | 1803 Ice::InstCast::OpKind CastKind; |
1734 if (!naclbitc::DecodeCastOpcode(Values[2], LLVMCastOp) || | 1804 if (!naclbitc::DecodeCastOpcode(Values[2], LLVMCastOp) || |
1735 !convertLLVMCastOpToIceOp(LLVMCastOp, CastKind)) { | 1805 !convertLLVMCastOpToIceOp(LLVMCastOp, CastKind)) { |
1736 std::string Buffer; | 1806 std::string Buffer; |
1737 raw_string_ostream StrBuf(Buffer); | 1807 raw_string_ostream StrBuf(Buffer); |
1738 StrBuf << "Cast opcode not understood: " << Values[2]; | 1808 StrBuf << "Cast opcode not understood: " << Values[2]; |
1739 Error(StrBuf.str()); | 1809 Error(StrBuf.str()); |
1740 appendErrorInstruction(CastType); | 1810 appendErrorInstruction(CastType); |
1741 return; | 1811 return; |
1742 } | 1812 } |
| 1813 if (isIRGenerationDisabled()) { |
| 1814 assert(Src == nullptr); |
| 1815 setNextLocalInstIndex(nullptr); |
| 1816 return; |
| 1817 } |
1743 Ice::Type SrcType = Src->getType(); | 1818 Ice::Type SrcType = Src->getType(); |
1744 if (!CastInst::castIsValid(LLVMCastOp, Context->convertToLLVMType(SrcType), | 1819 if (!CastInst::castIsValid(LLVMCastOp, Context->convertToLLVMType(SrcType), |
1745 Context->convertToLLVMType(CastType))) { | 1820 Context->convertToLLVMType(CastType))) { |
1746 std::string Buffer; | 1821 std::string Buffer; |
1747 raw_string_ostream StrBuf(Buffer); | 1822 raw_string_ostream StrBuf(Buffer); |
1748 StrBuf << "Illegal cast: " << Instruction::getOpcodeName(LLVMCastOp) | 1823 StrBuf << "Illegal cast: " << Instruction::getOpcodeName(LLVMCastOp) |
1749 << " " << SrcType << " to " << CastType; | 1824 << " " << SrcType << " to " << CastType; |
1750 Error(StrBuf.str()); | 1825 Error(StrBuf.str()); |
1751 appendErrorInstruction(CastType); | 1826 appendErrorInstruction(CastType); |
1752 return; | 1827 return; |
1753 } | 1828 } |
1754 CurrentNode->appendInst( | 1829 CurrentNode->appendInst( |
1755 Ice::InstCast::create(Func, CastKind, getNextInstVar(CastType), Src)); | 1830 Ice::InstCast::create(Func, CastKind, getNextInstVar(CastType), Src)); |
1756 return; | 1831 return; |
1757 } | 1832 } |
1758 case naclbitc::FUNC_CODE_INST_VSELECT: { | 1833 case naclbitc::FUNC_CODE_INST_VSELECT: { |
1759 // VSELECT: [opval, opval, pred] | 1834 // VSELECT: [opval, opval, pred] |
| 1835 if (!isValidRecordSize(3, "function block select")) |
| 1836 return; |
1760 Ice::Operand *ThenVal = getRelativeOperand(Values[0], BaseIndex); | 1837 Ice::Operand *ThenVal = getRelativeOperand(Values[0], BaseIndex); |
| 1838 Ice::Operand *ElseVal = getRelativeOperand(Values[1], BaseIndex); |
| 1839 Ice::Operand *CondVal = getRelativeOperand(Values[2], BaseIndex); |
| 1840 if (isIRGenerationDisabled()) { |
| 1841 assert(ThenVal == nullptr && ElseVal == nullptr && CondVal == nullptr); |
| 1842 setNextLocalInstIndex(nullptr); |
| 1843 return; |
| 1844 } |
1761 Ice::Type ThenType = ThenVal->getType(); | 1845 Ice::Type ThenType = ThenVal->getType(); |
1762 Ice::Operand *ElseVal = getRelativeOperand(Values[1], BaseIndex); | |
1763 Ice::Type ElseType = ElseVal->getType(); | 1846 Ice::Type ElseType = ElseVal->getType(); |
1764 if (ThenType != ElseType) { | 1847 if (ThenType != ElseType) { |
1765 std::string Buffer; | 1848 std::string Buffer; |
1766 raw_string_ostream StrBuf(Buffer); | 1849 raw_string_ostream StrBuf(Buffer); |
1767 StrBuf << "Select operands not same type. Found " << ThenType << " and " | 1850 StrBuf << "Select operands not same type. Found " << ThenType << " and " |
1768 << ElseType; | 1851 << ElseType; |
1769 Error(StrBuf.str()); | 1852 Error(StrBuf.str()); |
1770 appendErrorInstruction(ThenType); | 1853 appendErrorInstruction(ThenType); |
1771 return; | 1854 return; |
1772 } | 1855 } |
1773 Ice::Operand *CondVal = getRelativeOperand(Values[2], BaseIndex); | |
1774 Ice::Type CondType = CondVal->getType(); | 1856 Ice::Type CondType = CondVal->getType(); |
1775 if (isVectorType(CondType)) { | 1857 if (isVectorType(CondType)) { |
1776 if (!isVectorType(ThenType) || | 1858 if (!isVectorType(ThenType) || |
1777 typeElementType(CondType) != Ice::IceType_i1 || | 1859 typeElementType(CondType) != Ice::IceType_i1 || |
1778 typeNumElements(ThenType) != typeNumElements(CondType)) { | 1860 typeNumElements(ThenType) != typeNumElements(CondType)) { |
1779 std::string Buffer; | 1861 std::string Buffer; |
1780 raw_string_ostream StrBuf(Buffer); | 1862 raw_string_ostream StrBuf(Buffer); |
1781 StrBuf << "Select condition type " << CondType | 1863 StrBuf << "Select condition type " << CondType |
1782 << " not allowed for values of type " << ThenType; | 1864 << " not allowed for values of type " << ThenType; |
1783 Error(StrBuf.str()); | 1865 Error(StrBuf.str()); |
(...skipping 11 matching lines...) Expand all Loading... |
1795 } | 1877 } |
1796 CurrentNode->appendInst(Ice::InstSelect::create( | 1878 CurrentNode->appendInst(Ice::InstSelect::create( |
1797 Func, getNextInstVar(ThenType), CondVal, ThenVal, ElseVal)); | 1879 Func, getNextInstVar(ThenType), CondVal, ThenVal, ElseVal)); |
1798 return; | 1880 return; |
1799 } | 1881 } |
1800 case naclbitc::FUNC_CODE_INST_EXTRACTELT: { | 1882 case naclbitc::FUNC_CODE_INST_EXTRACTELT: { |
1801 // EXTRACTELT: [opval, opval] | 1883 // EXTRACTELT: [opval, opval] |
1802 if (!isValidRecordSize(2, "function block extract element")) | 1884 if (!isValidRecordSize(2, "function block extract element")) |
1803 return; | 1885 return; |
1804 Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex); | 1886 Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex); |
| 1887 Ice::Operand *Index = getRelativeOperand(Values[1], BaseIndex); |
| 1888 if (isIRGenerationDisabled()) { |
| 1889 assert(Vec == nullptr && Index == nullptr); |
| 1890 setNextLocalInstIndex(nullptr); |
| 1891 return; |
| 1892 } |
1805 Ice::Type VecType = Vec->getType(); | 1893 Ice::Type VecType = Vec->getType(); |
1806 Ice::Operand *Index = getRelativeOperand(Values[1], BaseIndex); | |
1807 VectorIndexCheckValue IndexCheckValue = validateVectorIndex(Vec, Index); | 1894 VectorIndexCheckValue IndexCheckValue = validateVectorIndex(Vec, Index); |
1808 if (IndexCheckValue != VectorIndexValid) { | 1895 if (IndexCheckValue != VectorIndexValid) { |
1809 std::string Buffer; | 1896 std::string Buffer; |
1810 raw_string_ostream StrBuf(Buffer); | 1897 raw_string_ostream StrBuf(Buffer); |
1811 dumpVectorIndexCheckValue(StrBuf, IndexCheckValue); | 1898 dumpVectorIndexCheckValue(StrBuf, IndexCheckValue); |
1812 StrBuf << ": extractelement " << VecType << " " << *Vec << ", " | 1899 StrBuf << ": extractelement " << VecType << " " << *Vec << ", " |
1813 << Index->getType() << " " << *Index; | 1900 << Index->getType() << " " << *Index; |
1814 Error(StrBuf.str()); | 1901 Error(StrBuf.str()); |
1815 appendErrorInstruction(VecType); | 1902 appendErrorInstruction(VecType); |
1816 return; | 1903 return; |
1817 } | 1904 } |
1818 CurrentNode->appendInst(Ice::InstExtractElement::create( | 1905 CurrentNode->appendInst(Ice::InstExtractElement::create( |
1819 Func, getNextInstVar(typeElementType(VecType)), Vec, Index)); | 1906 Func, getNextInstVar(typeElementType(VecType)), Vec, Index)); |
1820 return; | 1907 return; |
1821 } | 1908 } |
1822 case naclbitc::FUNC_CODE_INST_INSERTELT: { | 1909 case naclbitc::FUNC_CODE_INST_INSERTELT: { |
1823 // INSERTELT: [opval, opval, opval] | 1910 // INSERTELT: [opval, opval, opval] |
1824 if (!isValidRecordSize(3, "function block insert element")) | 1911 if (!isValidRecordSize(3, "function block insert element")) |
1825 return; | 1912 return; |
1826 Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex); | 1913 Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex); |
1827 Ice::Type VecType = Vec->getType(); | |
1828 Ice::Operand *Elt = getRelativeOperand(Values[1], BaseIndex); | 1914 Ice::Operand *Elt = getRelativeOperand(Values[1], BaseIndex); |
1829 Ice::Operand *Index = getRelativeOperand(Values[2], BaseIndex); | 1915 Ice::Operand *Index = getRelativeOperand(Values[2], BaseIndex); |
| 1916 if (isIRGenerationDisabled()) { |
| 1917 assert(Vec == nullptr && Elt == nullptr && Index == nullptr); |
| 1918 setNextLocalInstIndex(nullptr); |
| 1919 return; |
| 1920 } |
| 1921 Ice::Type VecType = Vec->getType(); |
1830 VectorIndexCheckValue IndexCheckValue = validateVectorIndex(Vec, Index); | 1922 VectorIndexCheckValue IndexCheckValue = validateVectorIndex(Vec, Index); |
1831 if (IndexCheckValue != VectorIndexValid) { | 1923 if (IndexCheckValue != VectorIndexValid) { |
1832 std::string Buffer; | 1924 std::string Buffer; |
1833 raw_string_ostream StrBuf(Buffer); | 1925 raw_string_ostream StrBuf(Buffer); |
1834 dumpVectorIndexCheckValue(StrBuf, IndexCheckValue); | 1926 dumpVectorIndexCheckValue(StrBuf, IndexCheckValue); |
1835 StrBuf << ": insertelement " << VecType << " " << *Vec << ", " | 1927 StrBuf << ": insertelement " << VecType << " " << *Vec << ", " |
1836 << Elt->getType() << " " << *Elt << ", " << Index->getType() << " " | 1928 << Elt->getType() << " " << *Elt << ", " << Index->getType() << " " |
1837 << *Index; | 1929 << *Index; |
1838 Error(StrBuf.str()); | 1930 Error(StrBuf.str()); |
1839 appendErrorInstruction(Elt->getType()); | 1931 appendErrorInstruction(Elt->getType()); |
1840 return; | 1932 return; |
1841 } | 1933 } |
1842 CurrentNode->appendInst(Ice::InstInsertElement::create( | 1934 CurrentNode->appendInst(Ice::InstInsertElement::create( |
1843 Func, getNextInstVar(VecType), Vec, Elt, Index)); | 1935 Func, getNextInstVar(VecType), Vec, Elt, Index)); |
1844 return; | 1936 return; |
1845 } | 1937 } |
1846 case naclbitc::FUNC_CODE_INST_CMP2: { | 1938 case naclbitc::FUNC_CODE_INST_CMP2: { |
1847 // CMP2: [opval, opval, pred] | 1939 // CMP2: [opval, opval, pred] |
1848 if (!isValidRecordSize(3, "function block compare")) | 1940 if (!isValidRecordSize(3, "function block compare")) |
1849 return; | 1941 return; |
1850 Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex); | 1942 Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex); |
1851 Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex); | 1943 Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex); |
| 1944 if (isIRGenerationDisabled()) { |
| 1945 assert(Op1 == nullptr && Op2 == nullptr); |
| 1946 setNextLocalInstIndex(nullptr); |
| 1947 return; |
| 1948 } |
1852 Ice::Type Op1Type = Op1->getType(); | 1949 Ice::Type Op1Type = Op1->getType(); |
1853 Ice::Type Op2Type = Op2->getType(); | 1950 Ice::Type Op2Type = Op2->getType(); |
1854 Ice::Type DestType = getCompareResultType(Op1Type); | 1951 Ice::Type DestType = getCompareResultType(Op1Type); |
1855 if (Op1Type != Op2Type) { | 1952 if (Op1Type != Op2Type) { |
1856 std::string Buffer; | 1953 std::string Buffer; |
1857 raw_string_ostream StrBuf(Buffer); | 1954 raw_string_ostream StrBuf(Buffer); |
1858 StrBuf << "Compare argument types differ: " << Op1Type | 1955 StrBuf << "Compare argument types differ: " << Op1Type |
1859 << " and " << Op2Type; | 1956 << " and " << Op2Type; |
1860 Error(StrBuf.str()); | 1957 Error(StrBuf.str()); |
1861 appendErrorInstruction(DestType); | 1958 appendErrorInstruction(DestType); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1902 appendErrorInstruction(DestType); | 1999 appendErrorInstruction(DestType); |
1903 return; | 2000 return; |
1904 } | 2001 } |
1905 return; | 2002 return; |
1906 } | 2003 } |
1907 case naclbitc::FUNC_CODE_INST_RET: { | 2004 case naclbitc::FUNC_CODE_INST_RET: { |
1908 // RET: [opval?] | 2005 // RET: [opval?] |
1909 if (!isValidRecordSizeInRange(0, 1, "function block ret")) | 2006 if (!isValidRecordSizeInRange(0, 1, "function block ret")) |
1910 return; | 2007 return; |
1911 if (Values.empty()) { | 2008 if (Values.empty()) { |
| 2009 if (isIRGenerationDisabled()) |
| 2010 return; |
1912 CurrentNode->appendInst(Ice::InstRet::create(Func)); | 2011 CurrentNode->appendInst(Ice::InstRet::create(Func)); |
1913 } else { | 2012 } else { |
1914 CurrentNode->appendInst( | 2013 Ice::Operand *RetVal = getRelativeOperand(Values[0], BaseIndex); |
1915 Ice::InstRet::create(Func, getRelativeOperand(Values[0], BaseIndex))); | 2014 if (isIRGenerationDisabled()) { |
| 2015 assert(RetVal == nullptr); |
| 2016 return; |
| 2017 } |
| 2018 CurrentNode->appendInst(Ice::InstRet::create(Func, RetVal)); |
1916 } | 2019 } |
1917 InstIsTerminating = true; | 2020 InstIsTerminating = true; |
1918 return; | 2021 return; |
1919 } | 2022 } |
1920 case naclbitc::FUNC_CODE_INST_BR: { | 2023 case naclbitc::FUNC_CODE_INST_BR: { |
1921 if (Values.size() == 1) { | 2024 if (Values.size() == 1) { |
1922 // BR: [bb#] | 2025 // BR: [bb#] |
| 2026 if (isIRGenerationDisabled()) |
| 2027 return; |
1923 Ice::CfgNode *Block = getBranchBasicBlock(Values[0]); | 2028 Ice::CfgNode *Block = getBranchBasicBlock(Values[0]); |
1924 if (Block == nullptr) | 2029 if (Block == nullptr) |
1925 return; | 2030 return; |
1926 CurrentNode->appendInst(Ice::InstBr::create(Func, Block)); | 2031 CurrentNode->appendInst(Ice::InstBr::create(Func, Block)); |
1927 } else { | 2032 } else { |
1928 // BR: [bb#, bb#, opval] | 2033 // BR: [bb#, bb#, opval] |
1929 if (!isValidRecordSize(3, "function block branch")) | 2034 if (!isValidRecordSize(3, "function block branch")) |
1930 return; | 2035 return; |
1931 Ice::Operand *Cond = getRelativeOperand(Values[2], BaseIndex); | 2036 Ice::Operand *Cond = getRelativeOperand(Values[2], BaseIndex); |
| 2037 if (isIRGenerationDisabled()) { |
| 2038 assert(Cond == nullptr); |
| 2039 return; |
| 2040 } |
1932 if (Cond->getType() != Ice::IceType_i1) { | 2041 if (Cond->getType() != Ice::IceType_i1) { |
1933 std::string Buffer; | 2042 std::string Buffer; |
1934 raw_string_ostream StrBuf(Buffer); | 2043 raw_string_ostream StrBuf(Buffer); |
1935 StrBuf << "Branch condition " << *Cond << " not i1. Found: " | 2044 StrBuf << "Branch condition " << *Cond << " not i1. Found: " |
1936 << Cond->getType(); | 2045 << Cond->getType(); |
1937 Error(StrBuf.str()); | 2046 Error(StrBuf.str()); |
1938 return; | 2047 return; |
1939 } | 2048 } |
1940 Ice::CfgNode *ThenBlock = getBranchBasicBlock(Values[0]); | 2049 Ice::CfgNode *ThenBlock = getBranchBasicBlock(Values[0]); |
1941 Ice::CfgNode *ElseBlock = getBranchBasicBlock(Values[1]); | 2050 Ice::CfgNode *ElseBlock = getBranchBasicBlock(Values[1]); |
1942 if (ThenBlock == nullptr || ElseBlock == nullptr) | 2051 if (ThenBlock == nullptr || ElseBlock == nullptr) |
1943 return; | 2052 return; |
1944 CurrentNode->appendInst( | 2053 CurrentNode->appendInst( |
1945 Ice::InstBr::create(Func, Cond, ThenBlock, ElseBlock)); | 2054 Ice::InstBr::create(Func, Cond, ThenBlock, ElseBlock)); |
1946 } | 2055 } |
1947 InstIsTerminating = true; | 2056 InstIsTerminating = true; |
1948 return; | 2057 return; |
1949 } | 2058 } |
1950 case naclbitc::FUNC_CODE_INST_SWITCH: { | 2059 case naclbitc::FUNC_CODE_INST_SWITCH: { |
1951 // SWITCH: [Condty, Cond, BbIndex, NumCases Case ...] | 2060 // SWITCH: [Condty, Cond, BbIndex, NumCases Case ...] |
1952 // where Case = [1, 1, Value, BbIndex]. | 2061 // where Case = [1, 1, Value, BbIndex]. |
1953 // | 2062 // |
1954 // Note: Unlike most instructions, we don't infer the type of | 2063 // Note: Unlike most instructions, we don't infer the type of |
1955 // Cond, but provide it as a separate field. There are also | 2064 // Cond, but provide it as a separate field. There are also |
1956 // unnecesary data fields (i.e. constants 1). These were not | 2065 // unnecesary data fields (i.e. constants 1). These were not |
1957 // cleaned up in PNaCl bitcode because the bitcode format was | 2066 // cleaned up in PNaCl bitcode because the bitcode format was |
1958 // already frozen when the problem was noticed. | 2067 // already frozen when the problem was noticed. |
1959 if (!isValidRecordSizeAtLeast(4, "function block switch")) | 2068 if (!isValidRecordSizeAtLeast(4, "function block switch")) |
1960 return; | 2069 return; |
| 2070 |
1961 Ice::Type CondTy = Context->getSimpleTypeByID(Values[0]); | 2071 Ice::Type CondTy = Context->getSimpleTypeByID(Values[0]); |
1962 if (!Ice::isScalarIntegerType(CondTy)) { | 2072 if (!Ice::isScalarIntegerType(CondTy)) { |
1963 std::string Buffer; | 2073 std::string Buffer; |
1964 raw_string_ostream StrBuf(Buffer); | 2074 raw_string_ostream StrBuf(Buffer); |
1965 StrBuf << "Case condition must be non-wide integer. Found: " << CondTy; | 2075 StrBuf << "Case condition must be non-wide integer. Found: " << CondTy; |
1966 Error(StrBuf.str()); | 2076 Error(StrBuf.str()); |
1967 return; | 2077 return; |
1968 } | 2078 } |
1969 Ice::SizeT BitWidth = Ice::getScalarIntBitWidth(CondTy); | 2079 Ice::SizeT BitWidth = Ice::getScalarIntBitWidth(CondTy); |
1970 Ice::Operand *Cond = getRelativeOperand(Values[1], BaseIndex); | 2080 Ice::Operand *Cond = getRelativeOperand(Values[1], BaseIndex); |
1971 if (CondTy != Cond->getType()) { | 2081 |
| 2082 const bool isIRGenDisabled = isIRGenerationDisabled(); |
| 2083 if (isIRGenDisabled) { |
| 2084 assert(Cond == nullptr); |
| 2085 } else if (CondTy != Cond->getType()) { |
1972 std::string Buffer; | 2086 std::string Buffer; |
1973 raw_string_ostream StrBuf(Buffer); | 2087 raw_string_ostream StrBuf(Buffer); |
1974 StrBuf << "Case condition expects type " << CondTy | 2088 StrBuf << "Case condition expects type " << CondTy |
1975 << ". Found: " << Cond->getType(); | 2089 << ". Found: " << Cond->getType(); |
1976 Error(StrBuf.str()); | 2090 Error(StrBuf.str()); |
1977 return; | 2091 return; |
1978 } | 2092 } |
1979 Ice::CfgNode *DefaultLabel = getBranchBasicBlock(Values[2]); | 2093 Ice::CfgNode *DefaultLabel = |
| 2094 isIRGenDisabled ? nullptr : getBranchBasicBlock(Values[2]); |
1980 unsigned NumCases = Values[3]; | 2095 unsigned NumCases = Values[3]; |
1981 | 2096 |
1982 // Now recognize each of the cases. | 2097 // Now recognize each of the cases. |
1983 if (!isValidRecordSize(4 + NumCases * 4, "Function block switch")) | 2098 if (!isValidRecordSize(4 + NumCases * 4, "Function block switch")) |
1984 return; | 2099 return; |
1985 Ice::InstSwitch *Switch = | 2100 Ice::InstSwitch *Switch = |
1986 Ice::InstSwitch::create(Func, NumCases, Cond, DefaultLabel); | 2101 isIRGenDisabled ? nullptr : Ice::InstSwitch::create(Func, NumCases, |
| 2102 Cond, DefaultLabel); |
1987 unsigned ValCaseIndex = 4; // index to beginning of case entry. | 2103 unsigned ValCaseIndex = 4; // index to beginning of case entry. |
1988 for (unsigned CaseIndex = 0; CaseIndex < NumCases; | 2104 for (unsigned CaseIndex = 0; CaseIndex < NumCases; |
1989 ++CaseIndex, ValCaseIndex += 4) { | 2105 ++CaseIndex, ValCaseIndex += 4) { |
1990 if (Values[ValCaseIndex] != 1 || Values[ValCaseIndex+1] != 1) { | 2106 if (Values[ValCaseIndex] != 1 || Values[ValCaseIndex+1] != 1) { |
1991 std::string Buffer; | 2107 std::string Buffer; |
1992 raw_string_ostream StrBuf(Buffer); | 2108 raw_string_ostream StrBuf(Buffer); |
1993 StrBuf << "Sequence [1, 1, value, label] expected for case entry " | 2109 StrBuf << "Sequence [1, 1, value, label] expected for case entry " |
1994 << "in switch record. (at index" << ValCaseIndex << ")"; | 2110 << "in switch record. (at index" << ValCaseIndex << ")"; |
1995 Error(StrBuf.str()); | 2111 Error(StrBuf.str()); |
1996 return; | 2112 return; |
1997 } | 2113 } |
1998 APInt Value(BitWidth, | 2114 APInt Value(BitWidth, |
1999 NaClDecodeSignRotatedValue(Values[ValCaseIndex + 2]), | 2115 NaClDecodeSignRotatedValue(Values[ValCaseIndex + 2]), |
2000 true); | 2116 true); |
| 2117 if (isIRGenDisabled) |
| 2118 continue; |
2001 Ice::CfgNode *Label = getBranchBasicBlock(Values[ValCaseIndex + 3]); | 2119 Ice::CfgNode *Label = getBranchBasicBlock(Values[ValCaseIndex + 3]); |
2002 Switch->addBranch(CaseIndex, Value.getSExtValue(), Label); | 2120 Switch->addBranch(CaseIndex, Value.getSExtValue(), Label); |
2003 } | 2121 } |
| 2122 if (isIRGenDisabled) |
| 2123 return; |
2004 CurrentNode->appendInst(Switch); | 2124 CurrentNode->appendInst(Switch); |
2005 InstIsTerminating = true; | 2125 InstIsTerminating = true; |
2006 return; | 2126 return; |
2007 } | 2127 } |
2008 case naclbitc::FUNC_CODE_INST_UNREACHABLE: { | 2128 case naclbitc::FUNC_CODE_INST_UNREACHABLE: { |
2009 // UNREACHABLE: [] | 2129 // UNREACHABLE: [] |
2010 if (!isValidRecordSize(0, "function block unreachable")) | 2130 if (!isValidRecordSize(0, "function block unreachable")) |
2011 return; | 2131 return; |
| 2132 if (isIRGenerationDisabled()) |
| 2133 return; |
2012 CurrentNode->appendInst( | 2134 CurrentNode->appendInst( |
2013 Ice::InstUnreachable::create(Func)); | 2135 Ice::InstUnreachable::create(Func)); |
2014 InstIsTerminating = true; | 2136 InstIsTerminating = true; |
2015 return; | 2137 return; |
2016 } | 2138 } |
2017 case naclbitc::FUNC_CODE_INST_PHI: { | 2139 case naclbitc::FUNC_CODE_INST_PHI: { |
2018 // PHI: [ty, val1, bb1, ..., valN, bbN] for n >= 2. | 2140 // PHI: [ty, val1, bb1, ..., valN, bbN] for n >= 2. |
2019 if (!isValidRecordSizeAtLeast(3, "function block phi")) | 2141 if (!isValidRecordSizeAtLeast(3, "function block phi")) |
2020 return; | 2142 return; |
2021 Ice::Type Ty = Context->getSimpleTypeByID(Values[0]); | 2143 Ice::Type Ty = Context->getSimpleTypeByID(Values[0]); |
2022 if ((Values.size() & 0x1) == 0) { | 2144 if ((Values.size() & 0x1) == 0) { |
2023 // Not an odd number of values. | 2145 // Not an odd number of values. |
2024 std::string Buffer; | 2146 std::string Buffer; |
2025 raw_string_ostream StrBuf(Buffer); | 2147 raw_string_ostream StrBuf(Buffer); |
2026 StrBuf << "function block phi record size not valid: " << Values.size(); | 2148 StrBuf << "function block phi record size not valid: " << Values.size(); |
2027 Error(StrBuf.str()); | 2149 Error(StrBuf.str()); |
2028 appendErrorInstruction(Ty); | 2150 appendErrorInstruction(Ty); |
2029 return; | 2151 return; |
2030 } | 2152 } |
2031 if (Ty == Ice::IceType_void) { | 2153 if (Ty == Ice::IceType_void) { |
2032 Error("Phi record using type void not allowed"); | 2154 Error("Phi record using type void not allowed"); |
2033 return; | 2155 return; |
2034 } | 2156 } |
| 2157 if (isIRGenerationDisabled()) { |
| 2158 // Verify arguments are defined before quitting. |
| 2159 for (unsigned i = 1; i < Values.size(); i += 2) { |
| 2160 assert(getRelativeOperand(NaClDecodeSignRotatedValue(Values[i]), |
| 2161 BaseIndex) == nullptr); |
| 2162 } |
| 2163 setNextLocalInstIndex(nullptr); |
| 2164 return; |
| 2165 } |
2035 Ice::Variable *Dest = getNextInstVar(Ty); | 2166 Ice::Variable *Dest = getNextInstVar(Ty); |
2036 Ice::InstPhi *Phi = Ice::InstPhi::create(Func, Values.size() >> 1, Dest); | 2167 Ice::InstPhi *Phi = Ice::InstPhi::create(Func, Values.size() >> 1, Dest); |
2037 for (unsigned i = 1; i < Values.size(); i += 2) { | 2168 for (unsigned i = 1; i < Values.size(); i += 2) { |
2038 Ice::Operand *Op = | 2169 Ice::Operand *Op = |
2039 getRelativeOperand(NaClDecodeSignRotatedValue(Values[i]), BaseIndex); | 2170 getRelativeOperand(NaClDecodeSignRotatedValue(Values[i]), BaseIndex); |
2040 if (Op->getType() != Ty) { | 2171 if (Op->getType() != Ty) { |
2041 std::string Buffer; | 2172 std::string Buffer; |
2042 raw_string_ostream StrBuf(Buffer); | 2173 raw_string_ostream StrBuf(Buffer); |
2043 StrBuf << "Value " << *Op << " not type " << Ty | 2174 StrBuf << "Value " << *Op << " not type " << Ty |
2044 << " in phi instruction. Found: " << Op->getType(); | 2175 << " in phi instruction. Found: " << Op->getType(); |
2045 Error(StrBuf.str()); | 2176 Error(StrBuf.str()); |
2046 appendErrorInstruction(Ty); | 2177 appendErrorInstruction(Ty); |
2047 return; | 2178 return; |
2048 } | 2179 } |
2049 Phi->addArgument(Op, getBasicBlock(Values[i + 1])); | 2180 Phi->addArgument(Op, getBasicBlock(Values[i + 1])); |
2050 } | 2181 } |
2051 CurrentNode->appendInst(Phi); | 2182 CurrentNode->appendInst(Phi); |
2052 return; | 2183 return; |
2053 } | 2184 } |
2054 case naclbitc::FUNC_CODE_INST_ALLOCA: { | 2185 case naclbitc::FUNC_CODE_INST_ALLOCA: { |
2055 // ALLOCA: [Size, align] | 2186 // ALLOCA: [Size, align] |
2056 if (!isValidRecordSize(2, "function block alloca")) | 2187 if (!isValidRecordSize(2, "function block alloca")) |
2057 return; | 2188 return; |
2058 Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex); | 2189 Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex); |
| 2190 unsigned Alignment; |
| 2191 extractAlignment("Alloca", Values[1], Alignment); |
| 2192 if (isIRGenerationDisabled()) { |
| 2193 assert(ByteCount == nullptr); |
| 2194 setNextLocalInstIndex(nullptr); |
| 2195 return; |
| 2196 } |
2059 Ice::Type PtrTy = Context->getIcePointerType(); | 2197 Ice::Type PtrTy = Context->getIcePointerType(); |
2060 if (ByteCount->getType() != Ice::IceType_i32) { | 2198 if (ByteCount->getType() != Ice::IceType_i32) { |
2061 std::string Buffer; | 2199 std::string Buffer; |
2062 raw_string_ostream StrBuf(Buffer); | 2200 raw_string_ostream StrBuf(Buffer); |
2063 StrBuf << "Alloca on non-i32 value. Found: " << *ByteCount; | 2201 StrBuf << "Alloca on non-i32 value. Found: " << *ByteCount; |
2064 Error(StrBuf.str()); | 2202 Error(StrBuf.str()); |
2065 appendErrorInstruction(PtrTy); | 2203 appendErrorInstruction(PtrTy); |
2066 return; | 2204 return; |
2067 } | 2205 } |
2068 unsigned Alignment; | |
2069 extractAlignment("Alloca", Values[1], Alignment); | |
2070 CurrentNode->appendInst(Ice::InstAlloca::create(Func, ByteCount, Alignment, | 2206 CurrentNode->appendInst(Ice::InstAlloca::create(Func, ByteCount, Alignment, |
2071 getNextInstVar(PtrTy))); | 2207 getNextInstVar(PtrTy))); |
2072 return; | 2208 return; |
2073 } | 2209 } |
2074 case naclbitc::FUNC_CODE_INST_LOAD: { | 2210 case naclbitc::FUNC_CODE_INST_LOAD: { |
2075 // LOAD: [address, align, ty] | 2211 // LOAD: [address, align, ty] |
2076 if (!isValidRecordSize(3, "function block load")) | 2212 if (!isValidRecordSize(3, "function block load")) |
2077 return; | 2213 return; |
2078 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); | 2214 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); |
2079 Ice::Type Ty = Context->getSimpleTypeByID(Values[2]); | 2215 Ice::Type Ty = Context->getSimpleTypeByID(Values[2]); |
| 2216 unsigned Alignment; |
| 2217 extractAlignment("Load", Values[1], Alignment); |
| 2218 if (isIRGenerationDisabled()) { |
| 2219 assert(Address == nullptr); |
| 2220 setNextLocalInstIndex(nullptr); |
| 2221 return; |
| 2222 } |
2080 if (!isValidPointerType(Address, "Load")) { | 2223 if (!isValidPointerType(Address, "Load")) { |
2081 appendErrorInstruction(Ty); | 2224 appendErrorInstruction(Ty); |
2082 return; | 2225 return; |
2083 } | 2226 } |
2084 unsigned Alignment; | |
2085 extractAlignment("Load", Values[1], Alignment); | |
2086 if (!isValidLoadStoreAlignment(Alignment, Ty, "Load")) { | 2227 if (!isValidLoadStoreAlignment(Alignment, Ty, "Load")) { |
2087 appendErrorInstruction(Ty); | 2228 appendErrorInstruction(Ty); |
2088 return; | 2229 return; |
2089 } | 2230 } |
2090 CurrentNode->appendInst( | 2231 CurrentNode->appendInst( |
2091 Ice::InstLoad::create(Func, getNextInstVar(Ty), Address, Alignment)); | 2232 Ice::InstLoad::create(Func, getNextInstVar(Ty), Address, Alignment)); |
2092 return; | 2233 return; |
2093 } | 2234 } |
2094 case naclbitc::FUNC_CODE_INST_STORE: { | 2235 case naclbitc::FUNC_CODE_INST_STORE: { |
2095 // STORE: [address, value, align] | 2236 // STORE: [address, value, align] |
2096 if (!isValidRecordSize(3, "function block store")) | 2237 if (!isValidRecordSize(3, "function block store")) |
2097 return; | 2238 return; |
2098 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); | 2239 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); |
2099 if (!isValidPointerType(Address, "Store")) | |
2100 return; | |
2101 Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex); | 2240 Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex); |
2102 unsigned Alignment; | 2241 unsigned Alignment; |
2103 extractAlignment("Store", Values[2], Alignment); | 2242 extractAlignment("Store", Values[2], Alignment); |
| 2243 if (isIRGenerationDisabled()) { |
| 2244 assert(Address == nullptr && Value == nullptr); |
| 2245 return; |
| 2246 } |
| 2247 if (!isValidPointerType(Address, "Store")) |
| 2248 return; |
2104 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store")) | 2249 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store")) |
2105 return; | 2250 return; |
2106 CurrentNode->appendInst( | 2251 CurrentNode->appendInst( |
2107 Ice::InstStore::create(Func, Value, Address, Alignment)); | 2252 Ice::InstStore::create(Func, Value, Address, Alignment)); |
2108 return; | 2253 return; |
2109 } | 2254 } |
2110 case naclbitc::FUNC_CODE_INST_CALL: | 2255 case naclbitc::FUNC_CODE_INST_CALL: |
2111 case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: { | 2256 case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: { |
2112 // CALL: [cc, fnid, arg0, arg1...] | 2257 // CALL: [cc, fnid, arg0, arg1...] |
2113 // CALL_INDIRECT: [cc, fn, returnty, args...] | 2258 // CALL_INDIRECT: [cc, fn, returnty, args...] |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2165 if (!naclbitc::DecodeCallingConv(CCInfo >> 1, CallingConv)) { | 2310 if (!naclbitc::DecodeCallingConv(CCInfo >> 1, CallingConv)) { |
2166 std::string Buffer; | 2311 std::string Buffer; |
2167 raw_string_ostream StrBuf(Buffer); | 2312 raw_string_ostream StrBuf(Buffer); |
2168 StrBuf << "Function call calling convention value " << (CCInfo >> 1) | 2313 StrBuf << "Function call calling convention value " << (CCInfo >> 1) |
2169 << " not understood."; | 2314 << " not understood."; |
2170 Error(StrBuf.str()); | 2315 Error(StrBuf.str()); |
2171 appendErrorInstruction(ReturnType); | 2316 appendErrorInstruction(ReturnType); |
2172 return; | 2317 return; |
2173 } | 2318 } |
2174 bool IsTailCall = static_cast<bool>(CCInfo & 1); | 2319 bool IsTailCall = static_cast<bool>(CCInfo & 1); |
| 2320 Ice::SizeT NumParams = Values.size() - ParamsStartIndex; |
| 2321 |
| 2322 if (isIRGenerationDisabled()) { |
| 2323 assert(Callee == nullptr); |
| 2324 // Check that parameters are defined. |
| 2325 for (Ice::SizeT ParamIndex = 0; ParamIndex < NumParams; ++ParamIndex) { |
| 2326 assert(getRelativeOperand(Values[ParamsStartIndex + ParamIndex], |
| 2327 BaseIndex) == nullptr); |
| 2328 } |
| 2329 // Define value slot only if value returned. |
| 2330 if (ReturnType != Ice::IceType_void) |
| 2331 setNextLocalInstIndex(nullptr); |
| 2332 return; |
| 2333 } |
2175 | 2334 |
2176 // Create the call instruction. | 2335 // Create the call instruction. |
2177 Ice::Variable *Dest = (ReturnType == Ice::IceType_void) | 2336 Ice::Variable *Dest = (ReturnType == Ice::IceType_void) |
2178 ? nullptr | 2337 ? nullptr |
2179 : getNextInstVar(ReturnType); | 2338 : getNextInstVar(ReturnType); |
2180 Ice::SizeT NumParams = Values.size() - ParamsStartIndex; | |
2181 Ice::InstCall *Inst = nullptr; | 2339 Ice::InstCall *Inst = nullptr; |
2182 if (IntrinsicInfo) { | 2340 if (IntrinsicInfo) { |
2183 Inst = | 2341 Inst = |
2184 Ice::InstIntrinsicCall::create(Func, NumParams, Dest, Callee, | 2342 Ice::InstIntrinsicCall::create(Func, NumParams, Dest, Callee, |
2185 IntrinsicInfo->Info); | 2343 IntrinsicInfo->Info); |
2186 } else { | 2344 } else { |
2187 Inst = Ice::InstCall::create(Func, NumParams, Dest, Callee, IsTailCall); | 2345 Inst = Ice::InstCall::create(Func, NumParams, Dest, Callee, IsTailCall); |
2188 } | 2346 } |
2189 | 2347 |
2190 // Add parameters. | 2348 // Add parameters. |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2235 } | 2393 } |
2236 } | 2394 } |
2237 | 2395 |
2238 CurrentNode->appendInst(Inst); | 2396 CurrentNode->appendInst(Inst); |
2239 return; | 2397 return; |
2240 } | 2398 } |
2241 case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF: { | 2399 case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF: { |
2242 // FORWARDTYPEREF: [opval, ty] | 2400 // FORWARDTYPEREF: [opval, ty] |
2243 if (!isValidRecordSize(2, "function block forward type ref")) | 2401 if (!isValidRecordSize(2, "function block forward type ref")) |
2244 return; | 2402 return; |
2245 setOperand(Values[0], createInstVar(Context->getSimpleTypeByID(Values[1]))); | 2403 Ice::Type OpType = Context->getSimpleTypeByID(Values[1]); |
| 2404 setOperand(Values[0], |
| 2405 isIRGenerationDisabled() ? nullptr : createInstVar(OpType)); |
2246 return; | 2406 return; |
2247 } | 2407 } |
2248 default: | 2408 default: |
2249 // Generate error message! | 2409 // Generate error message! |
2250 BlockParserBaseClass::ProcessRecord(); | 2410 BlockParserBaseClass::ProcessRecord(); |
2251 return; | 2411 return; |
2252 } | 2412 } |
2253 } | 2413 } |
2254 | 2414 |
2255 /// Parses constants within a function block. | 2415 /// Parses constants within a function block. |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2297 if (NextConstantType == Ice::IceType_void) | 2457 if (NextConstantType == Ice::IceType_void) |
2298 Error("constants block set type not allowed for void type"); | 2458 Error("constants block set type not allowed for void type"); |
2299 return; | 2459 return; |
2300 } | 2460 } |
2301 case naclbitc::CST_CODE_UNDEF: { | 2461 case naclbitc::CST_CODE_UNDEF: { |
2302 // UNDEF | 2462 // UNDEF |
2303 if (!isValidRecordSize(0, "constants block undef")) | 2463 if (!isValidRecordSize(0, "constants block undef")) |
2304 return; | 2464 return; |
2305 if (!isValidNextConstantType()) | 2465 if (!isValidNextConstantType()) |
2306 return; | 2466 return; |
| 2467 if (isIRGenerationDisabled()) { |
| 2468 FuncParser->setNextConstantID(nullptr); |
| 2469 return; |
| 2470 } |
2307 FuncParser->setNextConstantID( | 2471 FuncParser->setNextConstantID( |
2308 getContext()->getConstantUndef(NextConstantType)); | 2472 getContext()->getConstantUndef(NextConstantType)); |
2309 return; | 2473 return; |
2310 } | 2474 } |
2311 case naclbitc::CST_CODE_INTEGER: { | 2475 case naclbitc::CST_CODE_INTEGER: { |
2312 // INTEGER: [intval] | 2476 // INTEGER: [intval] |
2313 if (!isValidRecordSize(1, "constants block integer")) | 2477 if (!isValidRecordSize(1, "constants block integer")) |
2314 return; | 2478 return; |
2315 if (!isValidNextConstantType()) | 2479 if (!isValidNextConstantType()) |
2316 return; | 2480 return; |
| 2481 if (isIRGenerationDisabled()) { |
| 2482 FuncParser->setNextConstantID(nullptr); |
| 2483 return; |
| 2484 } |
2317 if (IntegerType *IType = dyn_cast<IntegerType>( | 2485 if (IntegerType *IType = dyn_cast<IntegerType>( |
2318 Context->convertToLLVMType(NextConstantType))) { | 2486 Context->convertToLLVMType(NextConstantType))) { |
2319 APInt Value(IType->getBitWidth(), NaClDecodeSignRotatedValue(Values[0])); | 2487 APInt Value(IType->getBitWidth(), NaClDecodeSignRotatedValue(Values[0])); |
2320 Ice::Constant *C = (NextConstantType == Ice::IceType_i64) | 2488 Ice::Constant *C = (NextConstantType == Ice::IceType_i64) |
2321 ? getContext()->getConstantInt64( | 2489 ? getContext()->getConstantInt64( |
2322 NextConstantType, Value.getSExtValue()) | 2490 NextConstantType, Value.getSExtValue()) |
2323 : getContext()->getConstantInt32( | 2491 : getContext()->getConstantInt32( |
2324 NextConstantType, Value.getSExtValue()); | 2492 NextConstantType, Value.getSExtValue()); |
2325 FuncParser->setNextConstantID(C); | 2493 FuncParser->setNextConstantID(C); |
2326 return; | 2494 return; |
2327 } | 2495 } |
2328 std::string Buffer; | 2496 std::string Buffer; |
2329 raw_string_ostream StrBuf(Buffer); | 2497 raw_string_ostream StrBuf(Buffer); |
2330 StrBuf << "constant block integer record for non-integer type " | 2498 StrBuf << "constant block integer record for non-integer type " |
2331 << NextConstantType; | 2499 << NextConstantType; |
2332 Error(StrBuf.str()); | 2500 Error(StrBuf.str()); |
2333 return; | 2501 return; |
2334 } | 2502 } |
2335 case naclbitc::CST_CODE_FLOAT: { | 2503 case naclbitc::CST_CODE_FLOAT: { |
2336 // FLOAT: [fpval] | 2504 // FLOAT: [fpval] |
2337 if (!isValidRecordSize(1, "constants block float")) | 2505 if (!isValidRecordSize(1, "constants block float")) |
2338 return; | 2506 return; |
2339 if (!isValidNextConstantType()) | 2507 if (!isValidNextConstantType()) |
2340 return; | 2508 return; |
| 2509 if (isIRGenerationDisabled()) { |
| 2510 FuncParser->setNextConstantID(nullptr); |
| 2511 return; |
| 2512 } |
2341 switch (NextConstantType) { | 2513 switch (NextConstantType) { |
2342 case Ice::IceType_f32: { | 2514 case Ice::IceType_f32: { |
2343 APFloat Value(APFloat::IEEEsingle, | 2515 APFloat Value(APFloat::IEEEsingle, |
2344 APInt(32, static_cast<uint32_t>(Values[0]))); | 2516 APInt(32, static_cast<uint32_t>(Values[0]))); |
2345 FuncParser->setNextConstantID( | 2517 FuncParser->setNextConstantID( |
2346 getContext()->getConstantFloat(Value.convertToFloat())); | 2518 getContext()->getConstantFloat(Value.convertToFloat())); |
2347 return; | 2519 return; |
2348 } | 2520 } |
2349 case Ice::IceType_f64: { | 2521 case Ice::IceType_f64: { |
2350 APFloat Value(APFloat::IEEEdouble, APInt(64, Values[0])); | 2522 APFloat Value(APFloat::IEEEdouble, APInt(64, Values[0])); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2403 }; | 2575 }; |
2404 | 2576 |
2405 void FunctionValuesymtabParser::setValueName(uint64_t Index, StringType &Name) { | 2577 void FunctionValuesymtabParser::setValueName(uint64_t Index, StringType &Name) { |
2406 // Note: We check when Index is too small, so that we can error recover | 2578 // Note: We check when Index is too small, so that we can error recover |
2407 // (FP->getOperand will create fatal error). | 2579 // (FP->getOperand will create fatal error). |
2408 if (Index < getFunctionParser()->CachedNumGlobalValueIDs) { | 2580 if (Index < getFunctionParser()->CachedNumGlobalValueIDs) { |
2409 reportUnableToAssign("instruction", Index, Name); | 2581 reportUnableToAssign("instruction", Index, Name); |
2410 // TODO(kschimpf) Remove error recovery once implementation complete. | 2582 // TODO(kschimpf) Remove error recovery once implementation complete. |
2411 return; | 2583 return; |
2412 } | 2584 } |
| 2585 if (isIRGenerationDisabled()) |
| 2586 return; |
2413 Ice::Operand *Op = getFunctionParser()->getOperand(Index); | 2587 Ice::Operand *Op = getFunctionParser()->getOperand(Index); |
2414 if (Ice::Variable *V = dyn_cast<Ice::Variable>(Op)) { | 2588 if (Ice::Variable *V = dyn_cast<Ice::Variable>(Op)) { |
2415 std::string Nm(Name.data(), Name.size()); | 2589 std::string Nm(Name.data(), Name.size()); |
2416 V->setName(Nm); | 2590 V->setName(Nm); |
2417 } else { | 2591 } else { |
2418 reportUnableToAssign("variable", Index, Name); | 2592 reportUnableToAssign("variable", Index, Name); |
2419 } | 2593 } |
2420 } | 2594 } |
2421 | 2595 |
2422 void FunctionValuesymtabParser::setBbName(uint64_t Index, StringType &Name) { | 2596 void FunctionValuesymtabParser::setBbName(uint64_t Index, StringType &Name) { |
| 2597 if (isIRGenerationDisabled()) |
| 2598 return; |
2423 if (Index >= getFunctionParser()->Func->getNumNodes()) { | 2599 if (Index >= getFunctionParser()->Func->getNumNodes()) { |
2424 reportUnableToAssign("block", Index, Name); | 2600 reportUnableToAssign("block", Index, Name); |
2425 return; | 2601 return; |
2426 } | 2602 } |
2427 std::string Nm(Name.data(), Name.size()); | 2603 std::string Nm(Name.data(), Name.size()); |
2428 getFunctionParser()->Func->getNodes()[Index]->setName(Nm); | 2604 getFunctionParser()->Func->getNodes()[Index]->setName(Nm); |
2429 } | 2605 } |
2430 | 2606 |
2431 bool FunctionParser::ParseBlock(unsigned BlockID) { | 2607 bool FunctionParser::ParseBlock(unsigned BlockID) { |
2432 switch (BlockID) { | 2608 switch (BlockID) { |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2682 | 2858 |
2683 if (TopLevelBlocks != 1) { | 2859 if (TopLevelBlocks != 1) { |
2684 errs() << IRFilename | 2860 errs() << IRFilename |
2685 << ": Contains more than one module. Found: " << TopLevelBlocks | 2861 << ": Contains more than one module. Found: " << TopLevelBlocks |
2686 << "\n"; | 2862 << "\n"; |
2687 ErrorStatus = true; | 2863 ErrorStatus = true; |
2688 } | 2864 } |
2689 } | 2865 } |
2690 | 2866 |
2691 } // end of namespace Ice | 2867 } // end of namespace Ice |
OLD | NEW |