OLD | NEW |
---|---|
1 //===- subzero/src/PNaClTranslator.cpp - ICE from bitcode -----------------===// | 1 //===- subzero/src/PNaClTranslator.cpp - ICE from bitcode -----------------===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 /// | 9 /// |
10 /// \file | 10 /// \file |
(...skipping 1197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1208 if (isIRGenerationDisabled()) { | 1208 if (isIRGenerationDisabled()) { |
1209 CurrentNode = nullptr; | 1209 CurrentNode = nullptr; |
1210 for (Ice::Type ArgType : Signature.getArgList()) { | 1210 for (Ice::Type ArgType : Signature.getArgList()) { |
1211 (void)ArgType; | 1211 (void)ArgType; |
1212 setNextLocalInstIndex(nullptr); | 1212 setNextLocalInstIndex(nullptr); |
1213 } | 1213 } |
1214 } else { | 1214 } else { |
1215 Func->setFunctionName(FuncDecl->getName()); | 1215 Func->setFunctionName(FuncDecl->getName()); |
1216 Func->setReturnType(Signature.getReturnType()); | 1216 Func->setReturnType(Signature.getReturnType()); |
1217 Func->setInternal(FuncDecl->getLinkage() == GlobalValue::InternalLinkage); | 1217 Func->setInternal(FuncDecl->getLinkage() == GlobalValue::InternalLinkage); |
1218 CurrentNode = installNextBasicBlock(); | 1218 constexpr NaClBcIndexSize_t EntryBlock = 0; |
1219 CurrentNode = getBasicBlock(EntryBlock); | |
1219 Func->setEntryNode(CurrentNode); | 1220 Func->setEntryNode(CurrentNode); |
1220 for (Ice::Type ArgType : Signature.getArgList()) { | 1221 for (Ice::Type ArgType : Signature.getArgList()) { |
1221 Func->addArg(getNextInstVar(ArgType)); | 1222 Func->addArg(getNextInstVar(ArgType)); |
1222 } | 1223 } |
1223 } | 1224 } |
1224 bool ParserResult = ParseThisBlock(); | 1225 bool ParserResult = ParseThisBlock(); |
1225 | 1226 |
1226 // Temporarily end per-function timing, which will be resumed by | 1227 // Temporarily end per-function timing, which will be resumed by |
1227 // the translator function. This is because translation may be | 1228 // the translator function. This is because translation may be |
1228 // done asynchronously in a separate thread. | 1229 // done asynchronously in a separate thread. |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1276 if (isIRGenerationDisabled()) | 1277 if (isIRGenerationDisabled()) |
1277 return nullptr; | 1278 return nullptr; |
1278 std::string Buffer; | 1279 std::string Buffer; |
1279 raw_string_ostream StrBuf(Buffer); | 1280 raw_string_ostream StrBuf(Buffer); |
1280 StrBuf << "Value index " << Index << " not defined!"; | 1281 StrBuf << "Value index " << Index << " not defined!"; |
1281 Fatal(StrBuf.str()); | 1282 Fatal(StrBuf.str()); |
1282 } | 1283 } |
1283 return Op; | 1284 return Op; |
1284 } | 1285 } |
1285 | 1286 |
1287 // Returns the Index-th basic block in the list of basic blocks. | |
1288 Ice::CfgNode *getBasicBlock(NaClBcIndexSize_t Index) { | |
1289 assert(!isIRGenerationDisabled()); | |
1290 CfgNodeMap::iterator pos = BbMap.find(Index); | |
Jim Stichnoth
2015/08/06 17:24:33
Pos
Karl
2015/08/06 18:55:52
Removed. Replaced with simpler code.
| |
1291 if (pos != BbMap.end()) | |
1292 return pos->second; | |
1293 Ice::CfgNode *Bb = Func->makeNode(); | |
1294 BbMap.insert(std::make_pair(Index, Bb)); | |
Jim Stichnoth
2015/08/06 17:24:33
I kinda prefer the clarity of this:
BbMap[Index]
Karl
2015/08/06 18:55:52
Did slight modification to your suggestion.
| |
1295 return Bb; | |
1296 } | |
1297 | |
1286 private: | 1298 private: |
1299 typedef std::map<NaClBcIndexSize_t, Ice::CfgNode*> CfgNodeMap; | |
Jim Stichnoth
2015/08/06 17:24:33
unordered_map
Karl
2015/08/06 18:55:52
Done.
| |
1300 | |
1287 Ice::TimerMarker Timer; | 1301 Ice::TimerMarker Timer; |
1288 // The corresponding ICE function defined by the function block. | 1302 // The corresponding ICE function defined by the function block. |
1289 std::unique_ptr<Ice::Cfg> Func; | 1303 std::unique_ptr<Ice::Cfg> Func; |
1304 // The specified number of basic blocks in the bitcode file. | |
1305 NaClBcIndexSize_t SpecifiedNumBbs = 0; | |
1290 // The index to the current basic block being built. | 1306 // The index to the current basic block being built. |
1291 NaClBcIndexSize_t CurrentBbIndex = 0; | 1307 NaClBcIndexSize_t CurrentBbIndex = 0; |
1292 // The basic block being built. | 1308 // The basic block being built. |
1293 Ice::CfgNode *CurrentNode = nullptr; | 1309 Ice::CfgNode *CurrentNode = nullptr; |
1310 // Map from basic block id (as defined in the bitcode file) to | |
1311 // the corresponding basic block that implements it. | |
1312 CfgNodeMap BbMap; | |
John
2015/08/06 17:22:54
The only operations you perform in BbMap are inser
Karl
2015/08/06 18:55:52
Changed to unordered map.
| |
1294 // The ID for the function. | 1313 // The ID for the function. |
1295 NaClBcIndexSize_t FcnId; | 1314 NaClBcIndexSize_t FcnId; |
1296 // The corresponding function declaration. | 1315 // The corresponding function declaration. |
1297 Ice::FunctionDeclaration *FuncDecl; | 1316 Ice::FunctionDeclaration *FuncDecl; |
1298 // Holds the dividing point between local and global absolute value indices. | 1317 // Holds the dividing point between local and global absolute value indices. |
1299 size_t CachedNumGlobalValueIDs; | 1318 size_t CachedNumGlobalValueIDs; |
1300 // Holds operands local to the function block, based on indices | 1319 // Holds operands local to the function block, based on indices |
1301 // defined in the bitcode file. | 1320 // defined in the bitcode file. |
1302 std::vector<Ice::Operand *> LocalOperands; | 1321 std::vector<Ice::Operand *> LocalOperands; |
1303 // Holds the index within LocalOperands corresponding to the next | 1322 // Holds the index within LocalOperands corresponding to the next |
(...skipping 22 matching lines...) Expand all Loading... | |
1326 // Error recover with value that is always acceptable. | 1345 // Error recover with value that is always acceptable. |
1327 Alignment = 1; | 1346 Alignment = 1; |
1328 } | 1347 } |
1329 | 1348 |
1330 bool ParseBlock(unsigned BlockID) override; | 1349 bool ParseBlock(unsigned BlockID) override; |
1331 | 1350 |
1332 void ProcessRecord() override; | 1351 void ProcessRecord() override; |
1333 | 1352 |
1334 void ExitBlock() override; | 1353 void ExitBlock() override; |
1335 | 1354 |
1336 // Creates and appends a new basic block to the list of basic blocks. | 1355 bool verifyAndRenameBasicBlocks(); |
1337 Ice::CfgNode *installNextBasicBlock() { | |
1338 assert(!isIRGenerationDisabled()); | |
1339 return Func->makeNode(); | |
1340 } | |
1341 | |
1342 // Returns the Index-th basic block in the list of basic blocks. | |
1343 Ice::CfgNode *getBasicBlock(NaClBcIndexSize_t Index) { | |
1344 assert(!isIRGenerationDisabled()); | |
1345 const Ice::NodeList &Nodes = Func->getNodes(); | |
1346 if (Index >= Nodes.size()) { | |
1347 std::string Buffer; | |
1348 raw_string_ostream StrBuf(Buffer); | |
1349 StrBuf << "Reference to basic block " << Index | |
1350 << " not found. Must be less than " << Nodes.size(); | |
1351 Error(StrBuf.str()); | |
1352 // TODO(kschimpf) Remove error recovery once implementation complete. | |
1353 Index = 0; | |
1354 } | |
1355 return Nodes[Index]; | |
1356 } | |
1357 | 1356 |
1358 // Returns the Index-th basic block in the list of basic blocks. | 1357 // Returns the Index-th basic block in the list of basic blocks. |
1359 // Assumes Index corresponds to a branch instruction. Hence, if | 1358 // Assumes Index corresponds to a branch instruction. Hence, if |
1360 // the branch references the entry block, it also generates a | 1359 // the branch references the entry block, it also generates a |
1361 // corresponding error. | 1360 // corresponding error. |
1362 Ice::CfgNode *getBranchBasicBlock(NaClBcIndexSize_t Index) { | 1361 Ice::CfgNode *getBranchBasicBlock(NaClBcIndexSize_t Index) { |
1363 assert(!isIRGenerationDisabled()); | 1362 assert(!isIRGenerationDisabled()); |
1364 if (Index == 0) { | 1363 if (Index == 0) { |
1365 Error("Branch to entry block not allowed"); | 1364 Error("Branch to entry block not allowed"); |
1366 // TODO(kschimpf) Remove error recovery once implementation complete. | 1365 // TODO(kschimpf) Remove error recovery once implementation complete. |
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1954 void appendErrorInstruction(Ice::Type Ty) { | 1953 void appendErrorInstruction(Ice::Type Ty) { |
1955 // Note: we don't worry about downstream translation errors because | 1954 // Note: we don't worry about downstream translation errors because |
1956 // the function will not be translated if any errors occur. | 1955 // the function will not be translated if any errors occur. |
1957 if (Ty == Ice::IceType_void) | 1956 if (Ty == Ice::IceType_void) |
1958 return; | 1957 return; |
1959 Ice::Variable *Var = getNextInstVar(Ty); | 1958 Ice::Variable *Var = getNextInstVar(Ty); |
1960 CurrentNode->appendInst(Ice::InstAssign::create(Func.get(), Var, Var)); | 1959 CurrentNode->appendInst(Ice::InstAssign::create(Func.get(), Var, Var)); |
1961 } | 1960 } |
1962 }; | 1961 }; |
1963 | 1962 |
1963 bool FunctionParser::verifyAndRenameBasicBlocks() { | |
1964 const size_t NumFoundBbs = BbMap.size(); | |
1965 // Verify number of basic blocks found match amount specified in function. | |
1966 if (NumFoundBbs != SpecifiedNumBbs) { | |
1967 std::string Buffer; | |
1968 raw_string_ostream StrBuf(Buffer); | |
1969 StrBuf << "Function specified " << SpecifiedNumBbs | |
Jim Stichnoth
2015/08/06 17:24:33
Add "blocks" or "basic blocks" to the message
Karl
2015/08/06 18:55:52
Done.
| |
1970 << ". Found: " << NumFoundBbs; | |
1971 Error(StrBuf.str()); | |
1972 return false; | |
1973 } | |
1974 // Verify size limit allowed for basic blocks. | |
1975 if (NumFoundBbs > NaClBcIndexSize_t_Max) { | |
1976 std::string Buffer; | |
1977 raw_string_ostream StrBuf(Buffer); | |
1978 StrBuf << "Functions can't define more than " << NaClBcIndexSize_t_Max | |
1979 << "basic blocks. Found: " << NumFoundBbs; | |
1980 Error(StrBuf.str()); | |
1981 return false; | |
1982 } | |
1983 // Sort list of Bbs, verifying that no basic blocks are missing. | |
1984 Ice::NodeList SortedBbs; | |
1985 for (size_t i = 0; i < NumFoundBbs; ++i) { | |
1986 CfgNodeMap::iterator pos = BbMap.find(i); | |
1987 if (pos == BbMap.end()) { | |
1988 std::string Buffer; | |
1989 raw_string_ostream StrBuf(Buffer); | |
1990 StrBuf << "Can't find definition for basic block " << i << "."; | |
1991 Error(StrBuf.str()); | |
1992 return false; | |
1993 } | |
1994 SortedBbs.push_back(pos->second); | |
1995 } | |
1996 // Install sorted basic blocks. | |
1997 Func->replaceNodes(SortedBbs); | |
1998 return true; | |
1999 } | |
2000 | |
1964 void FunctionParser::ExitBlock() { | 2001 void FunctionParser::ExitBlock() { |
1965 // Check if the last instruction in the function was terminating. | 2002 // Check if the last instruction in the function was terminating. |
1966 if (!InstIsTerminating) { | 2003 if (!InstIsTerminating) { |
1967 Error("Last instruction in function not terminator"); | 2004 Error("Last instruction in function not terminator"); |
1968 if (isIRGenerationDisabled()) | 2005 if (isIRGenerationDisabled()) |
1969 return; | 2006 return; |
1970 // Recover by inserting an unreachable instruction. | 2007 // Recover by inserting an unreachable instruction. |
1971 CurrentNode->appendInst(Ice::InstUnreachable::create(Func.get())); | 2008 CurrentNode->appendInst(Ice::InstUnreachable::create(Func.get())); |
1972 } | 2009 } |
1973 if (isIRGenerationDisabled()) | 2010 if (isIRGenerationDisabled()) |
1974 return; | 2011 return; |
2012 if (!verifyAndRenameBasicBlocks()) | |
2013 return; | |
1975 // Before translating, check for blocks without instructions, and | 2014 // Before translating, check for blocks without instructions, and |
1976 // insert unreachable. This shouldn't happen, but be safe. | 2015 // insert unreachable. This shouldn't happen, but be safe. |
1977 size_t Index = 0; | 2016 size_t Index = 0; |
1978 for (Ice::CfgNode *Node : Func->getNodes()) { | 2017 for (Ice::CfgNode *Node : Func->getNodes()) { |
1979 if (Node->getInsts().empty()) { | 2018 if (Node->getInsts().empty()) { |
1980 std::string Buffer; | 2019 std::string Buffer; |
1981 raw_string_ostream StrBuf(Buffer); | 2020 raw_string_ostream StrBuf(Buffer); |
1982 StrBuf << "Basic block " << Index << " contains no instructions"; | 2021 StrBuf << "Basic block " << Index << " contains no instructions"; |
1983 Error(StrBuf.str()); | 2022 Error(StrBuf.str()); |
1984 // TODO(kschimpf) Remove error recovery once implementation complete. | 2023 // TODO(kschimpf) Remove error recovery once implementation complete. |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2023 NumBbsRaw = 1; | 2062 NumBbsRaw = 1; |
2024 } else if (NumBbsRaw > NaClBcIndexSize_t_Max) { | 2063 } else if (NumBbsRaw > NaClBcIndexSize_t_Max) { |
2025 std::string Buffer; | 2064 std::string Buffer; |
2026 raw_string_ostream StrBuf(Buffer); | 2065 raw_string_ostream StrBuf(Buffer); |
2027 StrBuf << "To many basic blocks specified: " << NumBbsRaw; | 2066 StrBuf << "To many basic blocks specified: " << NumBbsRaw; |
2028 Error(StrBuf.str()); | 2067 Error(StrBuf.str()); |
2029 NumBbsRaw = NaClBcIndexSize_t_Max; | 2068 NumBbsRaw = NaClBcIndexSize_t_Max; |
2030 } | 2069 } |
2031 if (isIRGenerationDisabled()) | 2070 if (isIRGenerationDisabled()) |
2032 return; | 2071 return; |
2033 if (Func->getNodes().size() != 1) { | 2072 if (SpecifiedNumBbs != 0) { |
2034 Error("Duplicate function block count record"); | 2073 Error("Duplicate function block count record"); |
2035 return; | 2074 return; |
2036 } | 2075 } |
2037 // Install the basic blocks, skipping bb0 which was created in the | 2076 SpecifiedNumBbs = NumBbsRaw; |
2038 // constructor. | |
2039 for (size_t i = 1, NumBbs = NumBbsRaw; i < NumBbs; ++i) | |
2040 installNextBasicBlock(); | |
2041 return; | 2077 return; |
2042 } | 2078 } |
2043 case naclbitc::FUNC_CODE_INST_BINOP: { | 2079 case naclbitc::FUNC_CODE_INST_BINOP: { |
2044 // BINOP: [opval, opval, opcode] | 2080 // BINOP: [opval, opval, opcode] |
2045 if (!isValidRecordSize(3, "binop")) | 2081 if (!isValidRecordSize(3, "binop")) |
2046 return; | 2082 return; |
2047 Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex); | 2083 Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex); |
2048 Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex); | 2084 Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex); |
2049 if (isIRGenerationDisabled()) { | 2085 if (isIRGenerationDisabled()) { |
2050 assert(Op1 == nullptr && Op2 == nullptr); | 2086 assert(Op1 == nullptr && Op2 == nullptr); |
(...skipping 805 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2856 } | 2892 } |
2857 } else { | 2893 } else { |
2858 reportUnableToAssign("variable", Index, Name); | 2894 reportUnableToAssign("variable", Index, Name); |
2859 } | 2895 } |
2860 } | 2896 } |
2861 | 2897 |
2862 void FunctionValuesymtabParser::setBbName(NaClBcIndexSize_t Index, | 2898 void FunctionValuesymtabParser::setBbName(NaClBcIndexSize_t Index, |
2863 StringType &Name) { | 2899 StringType &Name) { |
2864 if (isIRGenerationDisabled()) | 2900 if (isIRGenerationDisabled()) |
2865 return; | 2901 return; |
2866 if (Index >= getFunctionParser()->getFunc()->getNumNodes()) { | 2902 Ice::CfgNode *Bb = getFunctionParser()->getBasicBlock(Index); |
2867 reportUnableToAssign("block", Index, Name); | 2903 if (Ice::BuildDefs::dump()) { |
Jim Stichnoth
2015/08/06 17:24:33
Can you put the BuildDefs::dump() check at the ver
Karl
2015/08/06 18:55:52
Done.
| |
2868 return; | 2904 std::string Nm(Name.data(), Name.size()); |
2905 Bb->setName(Nm); | |
2869 } | 2906 } |
2870 std::string Nm(Name.data(), Name.size()); | |
2871 if (Ice::BuildDefs::dump()) | |
2872 getFunctionParser()->getFunc()->getNodes()[Index]->setName(Nm); | |
2873 } | 2907 } |
2874 | 2908 |
2875 bool FunctionParser::ParseBlock(unsigned BlockID) { | 2909 bool FunctionParser::ParseBlock(unsigned BlockID) { |
2876 switch (BlockID) { | 2910 switch (BlockID) { |
2877 case naclbitc::CONSTANTS_BLOCK_ID: { | 2911 case naclbitc::CONSTANTS_BLOCK_ID: { |
2878 ConstantsParser Parser(BlockID, this); | 2912 ConstantsParser Parser(BlockID, this); |
2879 return Parser.ParseThisBlock(); | 2913 return Parser.ParseThisBlock(); |
2880 } | 2914 } |
2881 case naclbitc::VALUE_SYMTAB_BLOCK_ID: { | 2915 case naclbitc::VALUE_SYMTAB_BLOCK_ID: { |
2882 if (PNaClAllowLocalSymbolTables) { | 2916 if (PNaClAllowLocalSymbolTables) { |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3108 } | 3142 } |
3109 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { | 3143 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { |
3110 ErrStream | 3144 ErrStream |
3111 << IRFilename | 3145 << IRFilename |
3112 << ": Bitcode stream should be a multiple of 4 bytes in length.\n"; | 3146 << ": Bitcode stream should be a multiple of 4 bytes in length.\n"; |
3113 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); | 3147 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); |
3114 } | 3148 } |
3115 } | 3149 } |
3116 | 3150 |
3117 } // end of namespace Ice | 3151 } // end of namespace Ice |
OLD | NEW |