Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(77)

Side by Side Diff: src/PNaClTranslator.cpp

Issue 1275953002: Fix translator handling of basic block indices. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix issues in patch set 1. Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceCfg.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 18 matching lines...) Expand all
29 #pragma clang diagnostic ignored "-Wunused-parameter" 29 #pragma clang diagnostic ignored "-Wunused-parameter"
30 #include "llvm/ADT/SmallString.h" 30 #include "llvm/ADT/SmallString.h"
31 #include "llvm/Bitcode/NaCl/NaClBitcodeDecoders.h" 31 #include "llvm/Bitcode/NaCl/NaClBitcodeDecoders.h"
32 #include "llvm/Bitcode/NaCl/NaClBitcodeDefs.h" 32 #include "llvm/Bitcode/NaCl/NaClBitcodeDefs.h"
33 #include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h" 33 #include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h"
34 #include "llvm/Bitcode/NaCl/NaClBitcodeParser.h" 34 #include "llvm/Bitcode/NaCl/NaClBitcodeParser.h"
35 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h" 35 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h"
36 #include "llvm/Support/Format.h" 36 #include "llvm/Support/Format.h"
37 #include "llvm/Support/MemoryBuffer.h" 37 #include "llvm/Support/MemoryBuffer.h"
38 #include "llvm/Support/raw_ostream.h" 38 #include "llvm/Support/raw_ostream.h"
39 #include <unordered_map>
Jim Stichnoth 2015/08/06 19:41:21 Could you move this include into IceDefs.h, and re
Karl 2015/08/06 19:55:41 Done.
39 #pragma clang diagnostic pop 40 #pragma clang diagnostic pop
40 41
41 namespace { 42 namespace {
42 using namespace llvm; 43 using namespace llvm;
43 44
44 // Models elements in the list of types defined in the types block. 45 // Models elements in the list of types defined in the types block.
45 // These elements can be undefined, a (simple) type, or a function type 46 // These elements can be undefined, a (simple) type, or a function type
46 // signature. Note that an extended type is undefined on construction. 47 // signature. Note that an extended type is undefined on construction.
47 // Use methods setAsSimpleType and setAsFuncSigType to define 48 // Use methods setAsSimpleType and setAsFuncSigType to define
48 // the extended type. 49 // the extended type.
(...skipping 1159 matching lines...) Expand 10 before | Expand all | Expand 10 after
1208 if (isIRGenerationDisabled()) { 1209 if (isIRGenerationDisabled()) {
1209 CurrentNode = nullptr; 1210 CurrentNode = nullptr;
1210 for (Ice::Type ArgType : Signature.getArgList()) { 1211 for (Ice::Type ArgType : Signature.getArgList()) {
1211 (void)ArgType; 1212 (void)ArgType;
1212 setNextLocalInstIndex(nullptr); 1213 setNextLocalInstIndex(nullptr);
1213 } 1214 }
1214 } else { 1215 } else {
1215 Func->setFunctionName(FuncDecl->getName()); 1216 Func->setFunctionName(FuncDecl->getName());
1216 Func->setReturnType(Signature.getReturnType()); 1217 Func->setReturnType(Signature.getReturnType());
1217 Func->setInternal(FuncDecl->getLinkage() == GlobalValue::InternalLinkage); 1218 Func->setInternal(FuncDecl->getLinkage() == GlobalValue::InternalLinkage);
1218 CurrentNode = installNextBasicBlock(); 1219 constexpr NaClBcIndexSize_t EntryBlock = 0;
1220 CurrentNode = getBasicBlock(EntryBlock);
1219 Func->setEntryNode(CurrentNode); 1221 Func->setEntryNode(CurrentNode);
1220 for (Ice::Type ArgType : Signature.getArgList()) { 1222 for (Ice::Type ArgType : Signature.getArgList()) {
1221 Func->addArg(getNextInstVar(ArgType)); 1223 Func->addArg(getNextInstVar(ArgType));
1222 } 1224 }
1223 } 1225 }
1224 bool ParserResult = ParseThisBlock(); 1226 bool ParserResult = ParseThisBlock();
1225 1227
1226 // Temporarily end per-function timing, which will be resumed by 1228 // Temporarily end per-function timing, which will be resumed by
1227 // the translator function. This is because translation may be 1229 // the translator function. This is because translation may be
1228 // done asynchronously in a separate thread. 1230 // done asynchronously in a separate thread.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1276 if (isIRGenerationDisabled()) 1278 if (isIRGenerationDisabled())
1277 return nullptr; 1279 return nullptr;
1278 std::string Buffer; 1280 std::string Buffer;
1279 raw_string_ostream StrBuf(Buffer); 1281 raw_string_ostream StrBuf(Buffer);
1280 StrBuf << "Value index " << Index << " not defined!"; 1282 StrBuf << "Value index " << Index << " not defined!";
1281 Fatal(StrBuf.str()); 1283 Fatal(StrBuf.str());
1282 } 1284 }
1283 return Op; 1285 return Op;
1284 } 1286 }
1285 1287
1288 // Returns the Index-th basic block in the list of basic blocks.
1289 Ice::CfgNode *getBasicBlock(NaClBcIndexSize_t Index) {
1290 assert(!isIRGenerationDisabled());
1291 Ice::CfgNode *&Node = BbMap[Index];
1292 if (Node == nullptr)
1293 Node = Func->makeNode();
1294 return Node;
1295 }
1296
1286 private: 1297 private:
1298 typedef std::unordered_map<NaClBcIndexSize_t, Ice::CfgNode *> CfgNodeMap;
1299
1287 Ice::TimerMarker Timer; 1300 Ice::TimerMarker Timer;
1288 // The corresponding ICE function defined by the function block. 1301 // The corresponding ICE function defined by the function block.
1289 std::unique_ptr<Ice::Cfg> Func; 1302 std::unique_ptr<Ice::Cfg> Func;
1303 // The specified number of basic blocks in the bitcode file.
1304 NaClBcIndexSize_t SpecifiedNumBbs = 0;
1290 // The index to the current basic block being built. 1305 // The index to the current basic block being built.
1291 NaClBcIndexSize_t CurrentBbIndex = 0; 1306 NaClBcIndexSize_t CurrentBbIndex = 0;
1292 // The basic block being built. 1307 // The basic block being built.
1293 Ice::CfgNode *CurrentNode = nullptr; 1308 Ice::CfgNode *CurrentNode = nullptr;
1309 // Map from basic block id (as defined in the bitcode file) to
1310 // the corresponding basic block that implements it.
1311 CfgNodeMap BbMap;
1294 // The ID for the function. 1312 // The ID for the function.
1295 NaClBcIndexSize_t FcnId; 1313 NaClBcIndexSize_t FcnId;
1296 // The corresponding function declaration. 1314 // The corresponding function declaration.
1297 Ice::FunctionDeclaration *FuncDecl; 1315 Ice::FunctionDeclaration *FuncDecl;
1298 // Holds the dividing point between local and global absolute value indices. 1316 // Holds the dividing point between local and global absolute value indices.
1299 size_t CachedNumGlobalValueIDs; 1317 size_t CachedNumGlobalValueIDs;
1300 // Holds operands local to the function block, based on indices 1318 // Holds operands local to the function block, based on indices
1301 // defined in the bitcode file. 1319 // defined in the bitcode file.
1302 std::vector<Ice::Operand *> LocalOperands; 1320 std::vector<Ice::Operand *> LocalOperands;
1303 // Holds the index within LocalOperands corresponding to the next 1321 // Holds the index within LocalOperands corresponding to the next
(...skipping 22 matching lines...) Expand all
1326 // Error recover with value that is always acceptable. 1344 // Error recover with value that is always acceptable.
1327 Alignment = 1; 1345 Alignment = 1;
1328 } 1346 }
1329 1347
1330 bool ParseBlock(unsigned BlockID) override; 1348 bool ParseBlock(unsigned BlockID) override;
1331 1349
1332 void ProcessRecord() override; 1350 void ProcessRecord() override;
1333 1351
1334 void ExitBlock() override; 1352 void ExitBlock() override;
1335 1353
1336 // Creates and appends a new basic block to the list of basic blocks. 1354 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 1355
1358 // Returns the Index-th basic block in the list of basic blocks. 1356 // Returns the Index-th basic block in the list of basic blocks.
1359 // Assumes Index corresponds to a branch instruction. Hence, if 1357 // Assumes Index corresponds to a branch instruction. Hence, if
1360 // the branch references the entry block, it also generates a 1358 // the branch references the entry block, it also generates a
1361 // corresponding error. 1359 // corresponding error.
1362 Ice::CfgNode *getBranchBasicBlock(NaClBcIndexSize_t Index) { 1360 Ice::CfgNode *getBranchBasicBlock(NaClBcIndexSize_t Index) {
1363 assert(!isIRGenerationDisabled()); 1361 assert(!isIRGenerationDisabled());
1364 if (Index == 0) { 1362 if (Index == 0) {
1365 Error("Branch to entry block not allowed"); 1363 Error("Branch to entry block not allowed");
1366 // TODO(kschimpf) Remove error recovery once implementation complete. 1364 // TODO(kschimpf) Remove error recovery once implementation complete.
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after
1954 void appendErrorInstruction(Ice::Type Ty) { 1952 void appendErrorInstruction(Ice::Type Ty) {
1955 // Note: we don't worry about downstream translation errors because 1953 // Note: we don't worry about downstream translation errors because
1956 // the function will not be translated if any errors occur. 1954 // the function will not be translated if any errors occur.
1957 if (Ty == Ice::IceType_void) 1955 if (Ty == Ice::IceType_void)
1958 return; 1956 return;
1959 Ice::Variable *Var = getNextInstVar(Ty); 1957 Ice::Variable *Var = getNextInstVar(Ty);
1960 CurrentNode->appendInst(Ice::InstAssign::create(Func.get(), Var, Var)); 1958 CurrentNode->appendInst(Ice::InstAssign::create(Func.get(), Var, Var));
1961 } 1959 }
1962 }; 1960 };
1963 1961
1962 bool FunctionParser::verifyAndRenameBasicBlocks() {
1963 const size_t NumFoundBbs = BbMap.size();
1964 // Verify number of basic blocks found match amount specified in function.
1965 if (NumFoundBbs != SpecifiedNumBbs) {
1966 std::string Buffer;
1967 raw_string_ostream StrBuf(Buffer);
1968 StrBuf << "Function specified " << SpecifiedNumBbs
1969 << "basic blocks. Found: " << NumFoundBbs;
1970 Error(StrBuf.str());
1971 return false;
1972 }
1973 // Verify size limit allowed for basic blocks.
1974 if (NumFoundBbs > NaClBcIndexSize_t_Max) {
1975 std::string Buffer;
1976 raw_string_ostream StrBuf(Buffer);
1977 StrBuf << "Functions can't define more than " << NaClBcIndexSize_t_Max
1978 << "basic blocks. Found: " << NumFoundBbs;
1979 Error(StrBuf.str());
1980 return false;
1981 }
1982 // Sort list of Bbs, verifying that no basic blocks are missing.
1983 Ice::NodeList SortedBbs;
1984 for (size_t i = 0; i < NumFoundBbs; ++i) {
1985 CfgNodeMap::iterator pos = BbMap.find(i);
1986 if (pos == BbMap.end()) {
1987 std::string Buffer;
1988 raw_string_ostream StrBuf(Buffer);
1989 StrBuf << "Can't find definition for basic block " << i << ".";
1990 Error(StrBuf.str());
1991 return false;
1992 }
1993 SortedBbs.push_back(pos->second);
1994 }
1995 // Install sorted basic blocks.
1996 Func->swapNodes(SortedBbs);
1997 return true;
1998 }
1999
1964 void FunctionParser::ExitBlock() { 2000 void FunctionParser::ExitBlock() {
1965 // Check if the last instruction in the function was terminating. 2001 // Check if the last instruction in the function was terminating.
1966 if (!InstIsTerminating) { 2002 if (!InstIsTerminating) {
1967 Error("Last instruction in function not terminator"); 2003 Error("Last instruction in function not terminator");
1968 if (isIRGenerationDisabled()) 2004 if (isIRGenerationDisabled())
1969 return; 2005 return;
1970 // Recover by inserting an unreachable instruction. 2006 // Recover by inserting an unreachable instruction.
1971 CurrentNode->appendInst(Ice::InstUnreachable::create(Func.get())); 2007 CurrentNode->appendInst(Ice::InstUnreachable::create(Func.get()));
1972 } 2008 }
1973 if (isIRGenerationDisabled()) 2009 if (isIRGenerationDisabled())
1974 return; 2010 return;
2011 if (!verifyAndRenameBasicBlocks())
2012 return;
1975 // Before translating, check for blocks without instructions, and 2013 // Before translating, check for blocks without instructions, and
1976 // insert unreachable. This shouldn't happen, but be safe. 2014 // insert unreachable. This shouldn't happen, but be safe.
1977 size_t Index = 0; 2015 size_t Index = 0;
1978 for (Ice::CfgNode *Node : Func->getNodes()) { 2016 for (Ice::CfgNode *Node : Func->getNodes()) {
1979 if (Node->getInsts().empty()) { 2017 if (Node->getInsts().empty()) {
1980 std::string Buffer; 2018 std::string Buffer;
1981 raw_string_ostream StrBuf(Buffer); 2019 raw_string_ostream StrBuf(Buffer);
1982 StrBuf << "Basic block " << Index << " contains no instructions"; 2020 StrBuf << "Basic block " << Index << " contains no instructions";
1983 Error(StrBuf.str()); 2021 Error(StrBuf.str());
1984 // TODO(kschimpf) Remove error recovery once implementation complete. 2022 // TODO(kschimpf) Remove error recovery once implementation complete.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2023 NumBbsRaw = 1; 2061 NumBbsRaw = 1;
2024 } else if (NumBbsRaw > NaClBcIndexSize_t_Max) { 2062 } else if (NumBbsRaw > NaClBcIndexSize_t_Max) {
2025 std::string Buffer; 2063 std::string Buffer;
2026 raw_string_ostream StrBuf(Buffer); 2064 raw_string_ostream StrBuf(Buffer);
2027 StrBuf << "To many basic blocks specified: " << NumBbsRaw; 2065 StrBuf << "To many basic blocks specified: " << NumBbsRaw;
2028 Error(StrBuf.str()); 2066 Error(StrBuf.str());
2029 NumBbsRaw = NaClBcIndexSize_t_Max; 2067 NumBbsRaw = NaClBcIndexSize_t_Max;
2030 } 2068 }
2031 if (isIRGenerationDisabled()) 2069 if (isIRGenerationDisabled())
2032 return; 2070 return;
2033 if (Func->getNodes().size() != 1) { 2071 if (SpecifiedNumBbs != 0) {
2034 Error("Duplicate function block count record"); 2072 Error("Duplicate function block count record");
2035 return; 2073 return;
2036 } 2074 }
2037 // Install the basic blocks, skipping bb0 which was created in the 2075 SpecifiedNumBbs = NumBbsRaw;
2038 // constructor.
2039 for (size_t i = 1, NumBbs = NumBbsRaw; i < NumBbs; ++i)
2040 installNextBasicBlock();
2041 return; 2076 return;
2042 } 2077 }
2043 case naclbitc::FUNC_CODE_INST_BINOP: { 2078 case naclbitc::FUNC_CODE_INST_BINOP: {
2044 // BINOP: [opval, opval, opcode] 2079 // BINOP: [opval, opval, opcode]
2045 if (!isValidRecordSize(3, "binop")) 2080 if (!isValidRecordSize(3, "binop"))
2046 return; 2081 return;
2047 Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex); 2082 Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex);
2048 Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex); 2083 Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex);
2049 if (isIRGenerationDisabled()) { 2084 if (isIRGenerationDisabled()) {
2050 assert(Op1 == nullptr && Op2 == nullptr); 2085 assert(Op1 == nullptr && Op2 == nullptr);
(...skipping 803 matching lines...) Expand 10 before | Expand all | Expand 10 after
2854 std::string Nm(Name.data(), Name.size()); 2889 std::string Nm(Name.data(), Name.size());
2855 V->setName(getFunctionParser()->getFunc(), Nm); 2890 V->setName(getFunctionParser()->getFunc(), Nm);
2856 } 2891 }
2857 } else { 2892 } else {
2858 reportUnableToAssign("variable", Index, Name); 2893 reportUnableToAssign("variable", Index, Name);
2859 } 2894 }
2860 } 2895 }
2861 2896
2862 void FunctionValuesymtabParser::setBbName(NaClBcIndexSize_t Index, 2897 void FunctionValuesymtabParser::setBbName(NaClBcIndexSize_t Index,
2863 StringType &Name) { 2898 StringType &Name) {
2864 if (isIRGenerationDisabled()) 2899 if (isIRGenerationDisabled() || !Ice::BuildDefs::dump())
Jim Stichnoth 2015/08/06 19:41:21 Test for BuildDefs::dump() very first, even before
Karl 2015/08/06 19:55:41 Done.
2865 return; 2900 return;
2866 if (Index >= getFunctionParser()->getFunc()->getNumNodes()) { 2901 Ice::CfgNode *Bb = getFunctionParser()->getBasicBlock(Index);
2867 reportUnableToAssign("block", Index, Name);
2868 return;
2869 }
2870 std::string Nm(Name.data(), Name.size()); 2902 std::string Nm(Name.data(), Name.size());
2871 if (Ice::BuildDefs::dump()) 2903 Bb->setName(Nm);
2872 getFunctionParser()->getFunc()->getNodes()[Index]->setName(Nm);
2873 } 2904 }
2874 2905
2875 bool FunctionParser::ParseBlock(unsigned BlockID) { 2906 bool FunctionParser::ParseBlock(unsigned BlockID) {
2876 switch (BlockID) { 2907 switch (BlockID) {
2877 case naclbitc::CONSTANTS_BLOCK_ID: { 2908 case naclbitc::CONSTANTS_BLOCK_ID: {
2878 ConstantsParser Parser(BlockID, this); 2909 ConstantsParser Parser(BlockID, this);
2879 return Parser.ParseThisBlock(); 2910 return Parser.ParseThisBlock();
2880 } 2911 }
2881 case naclbitc::VALUE_SYMTAB_BLOCK_ID: { 2912 case naclbitc::VALUE_SYMTAB_BLOCK_ID: {
2882 if (PNaClAllowLocalSymbolTables) { 2913 if (PNaClAllowLocalSymbolTables) {
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
3108 } 3139 }
3109 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { 3140 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) {
3110 ErrStream 3141 ErrStream
3111 << IRFilename 3142 << IRFilename
3112 << ": Bitcode stream should be a multiple of 4 bytes in length.\n"; 3143 << ": 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"); 3144 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes");
3114 } 3145 }
3115 } 3146 }
3116 3147
3117 } // end of namespace Ice 3148 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceCfg.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698