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

Side by Side Diff: src/PNaClTranslator.cpp

Issue 1282523002: Fix processing of local variable indices in fuction blocks. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix nits 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 | « no previous file | 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 1288 matching lines...) Expand 10 before | Expand all | Expand 10 after
1299 1299
1300 // Set the next constant ID to the given constant C. 1300 // Set the next constant ID to the given constant C.
1301 void setNextConstantID(Ice::Constant *C) { setNextLocalInstIndex(C); } 1301 void setNextConstantID(Ice::Constant *C) { setNextLocalInstIndex(C); }
1302 1302
1303 // Returns the value referenced by the given value Index. 1303 // Returns the value referenced by the given value Index.
1304 Ice::Operand *getOperand(NaClBcIndexSize_t Index) { 1304 Ice::Operand *getOperand(NaClBcIndexSize_t Index) {
1305 if (Index < CachedNumGlobalValueIDs) { 1305 if (Index < CachedNumGlobalValueIDs) {
1306 return Context->getGlobalConstantByID(Index); 1306 return Context->getGlobalConstantByID(Index);
1307 } 1307 }
1308 NaClBcIndexSize_t LocalIndex = Index - CachedNumGlobalValueIDs; 1308 NaClBcIndexSize_t LocalIndex = Index - CachedNumGlobalValueIDs;
1309 if (LocalIndex >= LocalOperands.size()) {
1310 std::string Buffer;
1311 raw_string_ostream StrBuf(Buffer);
1312 StrBuf << "Value index " << Index << " not defined!";
1313 Fatal(StrBuf.str());
1314 }
1315 Ice::Operand *Op = LocalOperands[LocalIndex]; 1309 Ice::Operand *Op = LocalOperands[LocalIndex];
1316 if (Op == nullptr) { 1310 if (Op == nullptr) {
1317 if (isIRGenerationDisabled()) 1311 if (isIRGenerationDisabled())
1318 return nullptr; 1312 return nullptr;
1319 std::string Buffer; 1313 std::string Buffer;
1320 raw_string_ostream StrBuf(Buffer); 1314 raw_string_ostream StrBuf(Buffer);
1321 StrBuf << "Value index " << Index << " not defined!"; 1315 StrBuf << "Value index " << Index << " not defined!";
1322 Fatal(StrBuf.str()); 1316 Fatal(StrBuf.str());
1323 } 1317 }
1324 return Op; 1318 return Op;
1325 } 1319 }
1326 1320
1327 // Returns the Index-th basic block in the list of basic blocks. 1321 // Returns the Index-th basic block in the list of basic blocks.
1328 Ice::CfgNode *getBasicBlock(NaClBcIndexSize_t Index) { 1322 Ice::CfgNode *getBasicBlock(NaClBcIndexSize_t Index) {
1329 assert(!isIRGenerationDisabled()); 1323 assert(!isIRGenerationDisabled());
1330 Ice::CfgNode *&Node = BbMap[Index]; 1324 Ice::CfgNode *&Node = BbMap[Index];
1331 if (Node == nullptr) 1325 if (Node == nullptr)
1332 Node = Func->makeNode(); 1326 Node = Func->makeNode();
1333 return Node; 1327 return Node;
1334 } 1328 }
1335 1329
1336 private: 1330 private:
1331 typedef std::unordered_map<NaClBcIndexSize_t, Ice::Operand *> OperandMap;
1337 typedef std::unordered_map<NaClBcIndexSize_t, Ice::CfgNode *> CfgNodeMap; 1332 typedef std::unordered_map<NaClBcIndexSize_t, Ice::CfgNode *> CfgNodeMap;
1338 1333
1339 Ice::TimerMarker Timer; 1334 Ice::TimerMarker Timer;
1340 // The corresponding ICE function defined by the function block. 1335 // The corresponding ICE function defined by the function block.
1341 std::unique_ptr<Ice::Cfg> Func; 1336 std::unique_ptr<Ice::Cfg> Func;
1342 // The specified number of basic blocks in the bitcode file. 1337 // The specified number of basic blocks in the bitcode file.
1343 NaClBcIndexSize_t SpecifiedNumBbs = 0; 1338 NaClBcIndexSize_t SpecifiedNumBbs = 0;
1344 // The index to the current basic block being built. 1339 // The index to the current basic block being built.
1345 NaClBcIndexSize_t CurrentBbIndex = 0; 1340 NaClBcIndexSize_t CurrentBbIndex = 0;
1346 // The basic block being built. 1341 // The basic block being built.
1347 Ice::CfgNode *CurrentNode = nullptr; 1342 Ice::CfgNode *CurrentNode = nullptr;
1348 // Map from basic block id (as defined in the bitcode file) to 1343 // Map from basic block id (as defined in the bitcode file) to
1349 // the corresponding basic block that implements it. 1344 // the corresponding basic block that implements it.
1350 CfgNodeMap BbMap; 1345 CfgNodeMap BbMap;
1351 // The ID for the function. 1346 // The ID for the function.
1352 NaClBcIndexSize_t FcnId; 1347 NaClBcIndexSize_t FcnId;
1353 // The corresponding function declaration. 1348 // The corresponding function declaration.
1354 Ice::FunctionDeclaration *FuncDecl; 1349 Ice::FunctionDeclaration *FuncDecl;
1355 // Holds the dividing point between local and global absolute value indices. 1350 // Holds the dividing point between local and global absolute value indices.
1356 size_t CachedNumGlobalValueIDs; 1351 size_t CachedNumGlobalValueIDs;
1357 // Holds operands local to the function block, based on indices 1352 // Holds operands local to the function block, based on indices
1358 // defined in the bitcode file. 1353 // defined in the bitcode file.
1359 std::vector<Ice::Operand *> LocalOperands; 1354 OperandMap LocalOperands;
1360 // Holds the index within LocalOperands corresponding to the next 1355 // Holds the index within LocalOperands corresponding to the next
1361 // instruction that generates a value. 1356 // instruction that generates a value.
1362 NaClBcIndexSize_t NextLocalInstIndex; 1357 NaClBcIndexSize_t NextLocalInstIndex;
1363 // True if the last processed instruction was a terminating 1358 // True if the last processed instruction was a terminating
1364 // instruction. 1359 // instruction.
1365 bool InstIsTerminating = false; 1360 bool InstIsTerminating = false;
1366 // Upper limit of alignment power allowed by LLVM 1361 // Upper limit of alignment power allowed by LLVM
1367 static const uint32_t AlignPowerLimit = 29; 1362 static const uint32_t AlignPowerLimit = 29;
1368 1363
1369 // Extracts the corresponding Alignment to use, given the AlignPower 1364 // Extracts the corresponding Alignment to use, given the AlignPower
(...skipping 15 matching lines...) Expand all
1385 } 1380 }
1386 1381
1387 bool ParseBlock(unsigned BlockID) override; 1382 bool ParseBlock(unsigned BlockID) override;
1388 1383
1389 void ProcessRecord() override; 1384 void ProcessRecord() override;
1390 1385
1391 void ExitBlock() override; 1386 void ExitBlock() override;
1392 1387
1393 bool verifyAndRenameBasicBlocks(); 1388 bool verifyAndRenameBasicBlocks();
1394 1389
1390 bool verifyAllForwardRefsDefined();
1391
1395 // Returns the Index-th basic block in the list of basic blocks. 1392 // Returns the Index-th basic block in the list of basic blocks.
1396 // Assumes Index corresponds to a branch instruction. Hence, if 1393 // Assumes Index corresponds to a branch instruction. Hence, if
1397 // the branch references the entry block, it also generates a 1394 // the branch references the entry block, it also generates a
1398 // corresponding error. 1395 // corresponding error.
1399 Ice::CfgNode *getBranchBasicBlock(NaClBcIndexSize_t Index) { 1396 Ice::CfgNode *getBranchBasicBlock(NaClBcIndexSize_t Index) {
1400 assert(!isIRGenerationDisabled()); 1397 assert(!isIRGenerationDisabled());
1401 if (Index == 0) { 1398 if (Index == 0) {
1402 Error("Branch to entry block not allowed"); 1399 Error("Branch to entry block not allowed");
1403 // TODO(kschimpf) Remove error recovery once implementation complete. 1400 // TODO(kschimpf) Remove error recovery once implementation complete.
1404 } 1401 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1460 return 0; 1457 return 0;
1461 } 1458 }
1462 return BaseIndex - Id; 1459 return BaseIndex - Id;
1463 } 1460 }
1464 1461
1465 // Sets element Index (in the local operands list) to Op. 1462 // Sets element Index (in the local operands list) to Op.
1466 void setOperand(NaClBcIndexSize_t Index, Ice::Operand *Op) { 1463 void setOperand(NaClBcIndexSize_t Index, Ice::Operand *Op) {
1467 assert(Op || isIRGenerationDisabled()); 1464 assert(Op || isIRGenerationDisabled());
1468 // Check if simple push works. 1465 // Check if simple push works.
1469 NaClBcIndexSize_t LocalIndex = Index - CachedNumGlobalValueIDs; 1466 NaClBcIndexSize_t LocalIndex = Index - CachedNumGlobalValueIDs;
1470 if (LocalIndex == LocalOperands.size()) { 1467
1471 LocalOperands.push_back(Op); 1468 // If element not defined, set it.
1469 Ice::Operand *&IndexedOp = LocalOperands[LocalIndex];
1470 if (IndexedOp == nullptr) {
1471 IndexedOp = Op;
1472 return; 1472 return;
1473 } 1473 }
1474 1474
1475 // Must be forward reference, expand vector to accommodate. 1475 // See if forward reference matchers.
1476 if (LocalIndex >= LocalOperands.size()) 1476 if (IndexedOp == Op)
1477 LocalOperands.resize(LocalIndex + 1);
1478
1479 // If element not defined, set it.
1480 Ice::Operand *OldOp = LocalOperands[LocalIndex];
1481 if (OldOp == nullptr) {
1482 LocalOperands[LocalIndex] = Op;
1483 return;
1484 }
1485
1486 // See if forward reference matches.
1487 if (OldOp == Op)
1488 return; 1477 return;
1489 1478
1490 // Error has occurred. 1479 // Error has occurred.
1491 std::string Buffer; 1480 std::string Buffer;
1492 raw_string_ostream StrBuf(Buffer); 1481 raw_string_ostream StrBuf(Buffer);
1493 StrBuf << "Multiple definitions for index " << Index << ": " << *Op 1482 StrBuf << "Multiple definitions for index " << Index << ": " << *Op
1494 << " and " << *OldOp; 1483 << " and " << *IndexedOp;
1495 Error(StrBuf.str()); 1484 Error(StrBuf.str());
1496 // TODO(kschimpf) Remove error recovery once implementation complete. 1485 // TODO(kschimpf) Remove error recovery once implementation complete.
1497 LocalOperands[LocalIndex] = Op; 1486 IndexedOp = Op;
1498 } 1487 }
1499 1488
1500 // Returns the relative operand (wrt to BaseIndex) referenced by 1489 // Returns the relative operand (wrt to BaseIndex) referenced by
1501 // the given value Index. 1490 // the given value Index.
1502 Ice::Operand *getRelativeOperand(NaClBcIndexSize_t Index, 1491 Ice::Operand *getRelativeOperand(NaClBcIndexSize_t Index,
1503 NaClBcIndexSize_t BaseIndex) { 1492 NaClBcIndexSize_t BaseIndex) {
1504 return getOperand(convertRelativeToAbsIndex(Index, BaseIndex)); 1493 return getOperand(convertRelativeToAbsIndex(Index, BaseIndex));
1505 } 1494 }
1506 1495
1507 // Returns the absolute index of the next value generating instruction. 1496 // Returns the absolute index of the next value generating instruction.
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after
1991 void appendErrorInstruction(Ice::Type Ty) { 1980 void appendErrorInstruction(Ice::Type Ty) {
1992 // Note: we don't worry about downstream translation errors because 1981 // Note: we don't worry about downstream translation errors because
1993 // the function will not be translated if any errors occur. 1982 // the function will not be translated if any errors occur.
1994 if (Ty == Ice::IceType_void) 1983 if (Ty == Ice::IceType_void)
1995 return; 1984 return;
1996 Ice::Variable *Var = getNextInstVar(Ty); 1985 Ice::Variable *Var = getNextInstVar(Ty);
1997 CurrentNode->appendInst(Ice::InstAssign::create(Func.get(), Var, Var)); 1986 CurrentNode->appendInst(Ice::InstAssign::create(Func.get(), Var, Var));
1998 } 1987 }
1999 }; 1988 };
2000 1989
1990 bool FunctionParser::verifyAllForwardRefsDefined() {
1991 NaClBcIndexSize_t NumInstructions =
1992 NextLocalInstIndex - CachedNumGlobalValueIDs;
1993 if (NumInstructions == LocalOperands.size())
1994 return true;
1995 // Find undefined forward references and report.
1996 std::vector<NaClBcIndexSize_t> UndefinedFwdRefs;
1997 for (const OperandMap::value_type &Elmt : LocalOperands)
1998 if (Elmt.first >= NextLocalInstIndex)
1999 UndefinedFwdRefs.push_back(Elmt.first);
2000 std::sort(UndefinedFwdRefs.begin(), UndefinedFwdRefs.end());
2001 for (const NaClBcIndexSize_t Index : UndefinedFwdRefs) {
2002 std::string Buffer;
2003 raw_string_ostream StrBuf(Buffer);
2004 StrBuf << "Instruction forward reference not defined: " << Index;
2005 Error(StrBuf.str());
2006 }
2007 return false;
2008 }
2009
2001 bool FunctionParser::verifyAndRenameBasicBlocks() { 2010 bool FunctionParser::verifyAndRenameBasicBlocks() {
2002 const size_t NumFoundBbs = BbMap.size(); 2011 const size_t NumFoundBbs = BbMap.size();
2003 // Verify number of basic blocks found match amount specified in function. 2012 // Verify number of basic blocks found match amount specified in function.
2004 if (NumFoundBbs != SpecifiedNumBbs) { 2013 if (NumFoundBbs != SpecifiedNumBbs) {
2005 std::string Buffer; 2014 std::string Buffer;
2006 raw_string_ostream StrBuf(Buffer); 2015 raw_string_ostream StrBuf(Buffer);
2007 StrBuf << "Function specified " << SpecifiedNumBbs 2016 StrBuf << "Function specified " << SpecifiedNumBbs
2008 << "basic blocks. Found: " << NumFoundBbs; 2017 << "basic blocks. Found: " << NumFoundBbs;
2009 Error(StrBuf.str()); 2018 Error(StrBuf.str());
2010 return false; 2019 return false;
(...skipping 29 matching lines...) Expand all
2040 // Check if the last instruction in the function was terminating. 2049 // Check if the last instruction in the function was terminating.
2041 if (!InstIsTerminating) { 2050 if (!InstIsTerminating) {
2042 Error("Last instruction in function not terminator"); 2051 Error("Last instruction in function not terminator");
2043 if (isIRGenerationDisabled()) 2052 if (isIRGenerationDisabled())
2044 return; 2053 return;
2045 // Recover by inserting an unreachable instruction. 2054 // Recover by inserting an unreachable instruction.
2046 CurrentNode->appendInst(Ice::InstUnreachable::create(Func.get())); 2055 CurrentNode->appendInst(Ice::InstUnreachable::create(Func.get()));
2047 } 2056 }
2048 if (isIRGenerationDisabled()) 2057 if (isIRGenerationDisabled())
2049 return; 2058 return;
2059 if (!verifyAllForwardRefsDefined())
2060 return;
2050 if (!verifyAndRenameBasicBlocks()) 2061 if (!verifyAndRenameBasicBlocks())
2051 return; 2062 return;
2052 // Before translating, check for blocks without instructions, and 2063 // Before translating, check for blocks without instructions, and
2053 // insert unreachable. This shouldn't happen, but be safe. 2064 // insert unreachable. This shouldn't happen, but be safe.
2054 size_t Index = 0; 2065 size_t Index = 0;
2055 for (Ice::CfgNode *Node : Func->getNodes()) { 2066 for (Ice::CfgNode *Node : Func->getNodes()) {
2056 if (Node->getInsts().empty()) { 2067 if (Node->getInsts().empty()) {
2057 std::string Buffer; 2068 std::string Buffer;
2058 raw_string_ostream StrBuf(Buffer); 2069 raw_string_ostream StrBuf(Buffer);
2059 StrBuf << "Basic block " << Index << " contains no instructions"; 2070 StrBuf << "Basic block " << Index << " contains no instructions";
(...skipping 1120 matching lines...) Expand 10 before | Expand all | Expand 10 after
3180 } 3191 }
3181 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { 3192 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) {
3182 ErrStream 3193 ErrStream
3183 << IRFilename 3194 << IRFilename
3184 << ": Bitcode stream should be a multiple of 4 bytes in length.\n"; 3195 << ": Bitcode stream should be a multiple of 4 bytes in length.\n";
3185 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); 3196 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes");
3186 } 3197 }
3187 } 3198 }
3188 3199
3189 } // end of namespace Ice 3200 } // end of namespace Ice
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698