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

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 formatting. 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 1248 matching lines...) Expand 10 before | Expand all | Expand 10 after
1259 1259
1260 // Set the next constant ID to the given constant C. 1260 // Set the next constant ID to the given constant C.
1261 void setNextConstantID(Ice::Constant *C) { setNextLocalInstIndex(C); } 1261 void setNextConstantID(Ice::Constant *C) { setNextLocalInstIndex(C); }
1262 1262
1263 // Returns the value referenced by the given value Index. 1263 // Returns the value referenced by the given value Index.
1264 Ice::Operand *getOperand(NaClBcIndexSize_t Index) { 1264 Ice::Operand *getOperand(NaClBcIndexSize_t Index) {
1265 if (Index < CachedNumGlobalValueIDs) { 1265 if (Index < CachedNumGlobalValueIDs) {
1266 return Context->getGlobalConstantByID(Index); 1266 return Context->getGlobalConstantByID(Index);
1267 } 1267 }
1268 NaClBcIndexSize_t LocalIndex = Index - CachedNumGlobalValueIDs; 1268 NaClBcIndexSize_t LocalIndex = Index - CachedNumGlobalValueIDs;
1269 if (LocalIndex >= LocalOperands.size()) {
1270 std::string Buffer;
1271 raw_string_ostream StrBuf(Buffer);
1272 StrBuf << "Value index " << Index << " not defined!";
1273 Fatal(StrBuf.str());
1274 }
1275 Ice::Operand *Op = LocalOperands[LocalIndex]; 1269 Ice::Operand *Op = LocalOperands[LocalIndex];
1276 if (Op == nullptr) { 1270 if (Op == nullptr) {
1277 if (isIRGenerationDisabled()) 1271 if (isIRGenerationDisabled())
1278 return nullptr; 1272 return nullptr;
1279 std::string Buffer; 1273 std::string Buffer;
1280 raw_string_ostream StrBuf(Buffer); 1274 raw_string_ostream StrBuf(Buffer);
1281 StrBuf << "Value index " << Index << " not defined!"; 1275 StrBuf << "Value index " << Index << " not defined!";
1282 Fatal(StrBuf.str()); 1276 Fatal(StrBuf.str());
1283 } 1277 }
1284 return Op; 1278 return Op;
1285 } 1279 }
1286 1280
1287 // Returns the Index-th basic block in the list of basic blocks. 1281 // Returns the Index-th basic block in the list of basic blocks.
1288 Ice::CfgNode *getBasicBlock(NaClBcIndexSize_t Index) { 1282 Ice::CfgNode *getBasicBlock(NaClBcIndexSize_t Index) {
1289 assert(!isIRGenerationDisabled()); 1283 assert(!isIRGenerationDisabled());
1290 Ice::CfgNode *&Node = BbMap[Index]; 1284 Ice::CfgNode *&Node = BbMap[Index];
1291 if (Node == nullptr) 1285 if (Node == nullptr)
1292 Node = Func->makeNode(); 1286 Node = Func->makeNode();
1293 return Node; 1287 return Node;
1294 } 1288 }
1295 1289
1296 private: 1290 private:
1291 typedef std::unordered_map<NaClBcIndexSize_t, Ice::Operand *> OperandsMap;
Jim Stichnoth 2015/08/08 16:14:48 For naming consistency, I would use "OperandMap" o
Karl 2015/08/10 18:13:09 Done.
1297 typedef std::unordered_map<NaClBcIndexSize_t, Ice::CfgNode *> CfgNodeMap; 1292 typedef std::unordered_map<NaClBcIndexSize_t, Ice::CfgNode *> CfgNodeMap;
1298 1293
1299 Ice::TimerMarker Timer; 1294 Ice::TimerMarker Timer;
1300 // The corresponding ICE function defined by the function block. 1295 // The corresponding ICE function defined by the function block.
1301 std::unique_ptr<Ice::Cfg> Func; 1296 std::unique_ptr<Ice::Cfg> Func;
1302 // The specified number of basic blocks in the bitcode file. 1297 // The specified number of basic blocks in the bitcode file.
1303 NaClBcIndexSize_t SpecifiedNumBbs = 0; 1298 NaClBcIndexSize_t SpecifiedNumBbs = 0;
1304 // The index to the current basic block being built. 1299 // The index to the current basic block being built.
1305 NaClBcIndexSize_t CurrentBbIndex = 0; 1300 NaClBcIndexSize_t CurrentBbIndex = 0;
1306 // The basic block being built. 1301 // The basic block being built.
1307 Ice::CfgNode *CurrentNode = nullptr; 1302 Ice::CfgNode *CurrentNode = nullptr;
1308 // Map from basic block id (as defined in the bitcode file) to 1303 // Map from basic block id (as defined in the bitcode file) to
1309 // the corresponding basic block that implements it. 1304 // the corresponding basic block that implements it.
1310 CfgNodeMap BbMap; 1305 CfgNodeMap BbMap;
1311 // The ID for the function. 1306 // The ID for the function.
1312 NaClBcIndexSize_t FcnId; 1307 NaClBcIndexSize_t FcnId;
1313 // The corresponding function declaration. 1308 // The corresponding function declaration.
1314 Ice::FunctionDeclaration *FuncDecl; 1309 Ice::FunctionDeclaration *FuncDecl;
1315 // Holds the dividing point between local and global absolute value indices. 1310 // Holds the dividing point between local and global absolute value indices.
1316 size_t CachedNumGlobalValueIDs; 1311 size_t CachedNumGlobalValueIDs;
1317 // Holds operands local to the function block, based on indices 1312 // Holds operands local to the function block, based on indices
1318 // defined in the bitcode file. 1313 // defined in the bitcode file.
1319 std::vector<Ice::Operand *> LocalOperands; 1314 OperandsMap LocalOperands;
1320 // Holds the index within LocalOperands corresponding to the next 1315 // Holds the index within LocalOperands corresponding to the next
1321 // instruction that generates a value. 1316 // instruction that generates a value.
1322 NaClBcIndexSize_t NextLocalInstIndex; 1317 NaClBcIndexSize_t NextLocalInstIndex;
1323 // True if the last processed instruction was a terminating 1318 // True if the last processed instruction was a terminating
1324 // instruction. 1319 // instruction.
1325 bool InstIsTerminating = false; 1320 bool InstIsTerminating = false;
1326 // Upper limit of alignment power allowed by LLVM 1321 // Upper limit of alignment power allowed by LLVM
1327 static const uint32_t AlignPowerLimit = 29; 1322 static const uint32_t AlignPowerLimit = 29;
1328 1323
1329 // Extracts the corresponding Alignment to use, given the AlignPower 1324 // Extracts the corresponding Alignment to use, given the AlignPower
(...skipping 15 matching lines...) Expand all
1345 } 1340 }
1346 1341
1347 bool ParseBlock(unsigned BlockID) override; 1342 bool ParseBlock(unsigned BlockID) override;
1348 1343
1349 void ProcessRecord() override; 1344 void ProcessRecord() override;
1350 1345
1351 void ExitBlock() override; 1346 void ExitBlock() override;
1352 1347
1353 bool verifyAndRenameBasicBlocks(); 1348 bool verifyAndRenameBasicBlocks();
1354 1349
1350 bool verifyAllForwardRefsDefined();
1351
1355 // Returns the Index-th basic block in the list of basic blocks. 1352 // Returns the Index-th basic block in the list of basic blocks.
1356 // Assumes Index corresponds to a branch instruction. Hence, if 1353 // Assumes Index corresponds to a branch instruction. Hence, if
1357 // the branch references the entry block, it also generates a 1354 // the branch references the entry block, it also generates a
1358 // corresponding error. 1355 // corresponding error.
1359 Ice::CfgNode *getBranchBasicBlock(NaClBcIndexSize_t Index) { 1356 Ice::CfgNode *getBranchBasicBlock(NaClBcIndexSize_t Index) {
1360 assert(!isIRGenerationDisabled()); 1357 assert(!isIRGenerationDisabled());
1361 if (Index == 0) { 1358 if (Index == 0) {
1362 Error("Branch to entry block not allowed"); 1359 Error("Branch to entry block not allowed");
1363 // TODO(kschimpf) Remove error recovery once implementation complete. 1360 // TODO(kschimpf) Remove error recovery once implementation complete.
1364 } 1361 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1420 return 0; 1417 return 0;
1421 } 1418 }
1422 return BaseIndex - Id; 1419 return BaseIndex - Id;
1423 } 1420 }
1424 1421
1425 // Sets element Index (in the local operands list) to Op. 1422 // Sets element Index (in the local operands list) to Op.
1426 void setOperand(NaClBcIndexSize_t Index, Ice::Operand *Op) { 1423 void setOperand(NaClBcIndexSize_t Index, Ice::Operand *Op) {
1427 assert(Op || isIRGenerationDisabled()); 1424 assert(Op || isIRGenerationDisabled());
1428 // Check if simple push works. 1425 // Check if simple push works.
1429 NaClBcIndexSize_t LocalIndex = Index - CachedNumGlobalValueIDs; 1426 NaClBcIndexSize_t LocalIndex = Index - CachedNumGlobalValueIDs;
1430 if (LocalIndex == LocalOperands.size()) { 1427
1431 LocalOperands.push_back(Op); 1428 // If element not defined, set it.
1429 Ice::Operand *&IndexedOp = LocalOperands[LocalIndex];
1430 if (IndexedOp == nullptr) {
1431 IndexedOp = Op;
1432 return; 1432 return;
1433 } 1433 }
1434 1434
1435 // Must be forward reference, expand vector to accommodate. 1435 // See if forward reference matchers.
1436 if (LocalIndex >= LocalOperands.size()) 1436 if (IndexedOp == Op)
1437 LocalOperands.resize(LocalIndex + 1);
1438
1439 // If element not defined, set it.
1440 Ice::Operand *OldOp = LocalOperands[LocalIndex];
1441 if (OldOp == nullptr) {
1442 LocalOperands[LocalIndex] = Op;
1443 return;
1444 }
1445
1446 // See if forward reference matches.
1447 if (OldOp == Op)
1448 return; 1437 return;
1449 1438
1450 // Error has occurred. 1439 // Error has occurred.
1451 std::string Buffer; 1440 std::string Buffer;
1452 raw_string_ostream StrBuf(Buffer); 1441 raw_string_ostream StrBuf(Buffer);
1453 StrBuf << "Multiple definitions for index " << Index << ": " << *Op 1442 StrBuf << "Multiple definitions for index " << Index << ": " << *Op
1454 << " and " << *OldOp; 1443 << " and " << *IndexedOp;
1455 Error(StrBuf.str()); 1444 Error(StrBuf.str());
1456 // TODO(kschimpf) Remove error recovery once implementation complete. 1445 // TODO(kschimpf) Remove error recovery once implementation complete.
Jim Stichnoth 2015/08/08 16:14:48 Trying to remember the context of these TODOs...
Karl 2015/08/10 18:13:09 This was back when someone wasn't sure we should k
1457 LocalOperands[LocalIndex] = Op; 1446 IndexedOp = Op;
1458 } 1447 }
1459 1448
1460 // Returns the relative operand (wrt to BaseIndex) referenced by 1449 // Returns the relative operand (wrt to BaseIndex) referenced by
1461 // the given value Index. 1450 // the given value Index.
1462 Ice::Operand *getRelativeOperand(NaClBcIndexSize_t Index, 1451 Ice::Operand *getRelativeOperand(NaClBcIndexSize_t Index,
1463 NaClBcIndexSize_t BaseIndex) { 1452 NaClBcIndexSize_t BaseIndex) {
1464 return getOperand(convertRelativeToAbsIndex(Index, BaseIndex)); 1453 return getOperand(convertRelativeToAbsIndex(Index, BaseIndex));
1465 } 1454 }
1466 1455
1467 // Returns the absolute index of the next value generating instruction. 1456 // Returns the absolute index of the next value generating instruction.
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after
1951 void appendErrorInstruction(Ice::Type Ty) { 1940 void appendErrorInstruction(Ice::Type Ty) {
1952 // Note: we don't worry about downstream translation errors because 1941 // Note: we don't worry about downstream translation errors because
1953 // the function will not be translated if any errors occur. 1942 // the function will not be translated if any errors occur.
1954 if (Ty == Ice::IceType_void) 1943 if (Ty == Ice::IceType_void)
1955 return; 1944 return;
1956 Ice::Variable *Var = getNextInstVar(Ty); 1945 Ice::Variable *Var = getNextInstVar(Ty);
1957 CurrentNode->appendInst(Ice::InstAssign::create(Func.get(), Var, Var)); 1946 CurrentNode->appendInst(Ice::InstAssign::create(Func.get(), Var, Var));
1958 } 1947 }
1959 }; 1948 };
1960 1949
1950 bool FunctionParser::verifyAllForwardRefsDefined() {
1951 NaClBcIndexSize_t NumInstructions =
1952 NextLocalInstIndex - CachedNumGlobalValueIDs;
1953 if (NumInstructions == LocalOperands.size())
1954 return true;
1955 // Find undefined forward references and report.
1956 std::vector<NaClBcIndexSize_t> UndefinedFwdRefs;
1957 for (const std::pair<NaClBcIndexSize_t, Ice::Operand *> Elmt : LocalOperands)
Jim Stichnoth 2015/08/08 16:14:48 I think this calls for auto: for (auto &Elmt :
Karl 2015/08/10 18:13:09 Good point. I didn't put the auto in because I did
1958 if (Elmt.first >= NextLocalInstIndex)
1959 UndefinedFwdRefs.push_back(Elmt.first);
1960 std::sort(UndefinedFwdRefs.begin(), UndefinedFwdRefs.end());
1961 for (const NaClBcIndexSize_t Index : UndefinedFwdRefs) {
1962 std::string Buffer;
1963 raw_string_ostream StrBuf(Buffer);
1964 StrBuf << "Instruction forward reference not defined: " << Index;
1965 Error(StrBuf.str());
1966 }
1967 return false;
1968 }
1969
1961 bool FunctionParser::verifyAndRenameBasicBlocks() { 1970 bool FunctionParser::verifyAndRenameBasicBlocks() {
1962 const size_t NumFoundBbs = BbMap.size(); 1971 const size_t NumFoundBbs = BbMap.size();
1963 // Verify number of basic blocks found match amount specified in function. 1972 // Verify number of basic blocks found match amount specified in function.
1964 if (NumFoundBbs != SpecifiedNumBbs) { 1973 if (NumFoundBbs != SpecifiedNumBbs) {
1965 std::string Buffer; 1974 std::string Buffer;
1966 raw_string_ostream StrBuf(Buffer); 1975 raw_string_ostream StrBuf(Buffer);
1967 StrBuf << "Function specified " << SpecifiedNumBbs 1976 StrBuf << "Function specified " << SpecifiedNumBbs
1968 << "basic blocks. Found: " << NumFoundBbs; 1977 << "basic blocks. Found: " << NumFoundBbs;
1969 Error(StrBuf.str()); 1978 Error(StrBuf.str());
1970 return false; 1979 return false;
(...skipping 29 matching lines...) Expand all
2000 // Check if the last instruction in the function was terminating. 2009 // Check if the last instruction in the function was terminating.
2001 if (!InstIsTerminating) { 2010 if (!InstIsTerminating) {
2002 Error("Last instruction in function not terminator"); 2011 Error("Last instruction in function not terminator");
2003 if (isIRGenerationDisabled()) 2012 if (isIRGenerationDisabled())
2004 return; 2013 return;
2005 // Recover by inserting an unreachable instruction. 2014 // Recover by inserting an unreachable instruction.
2006 CurrentNode->appendInst(Ice::InstUnreachable::create(Func.get())); 2015 CurrentNode->appendInst(Ice::InstUnreachable::create(Func.get()));
2007 } 2016 }
2008 if (isIRGenerationDisabled()) 2017 if (isIRGenerationDisabled())
2009 return; 2018 return;
2019 if (!verifyAllForwardRefsDefined())
2020 return;
2010 if (!verifyAndRenameBasicBlocks()) 2021 if (!verifyAndRenameBasicBlocks())
2011 return; 2022 return;
2012 // Before translating, check for blocks without instructions, and 2023 // Before translating, check for blocks without instructions, and
2013 // insert unreachable. This shouldn't happen, but be safe. 2024 // insert unreachable. This shouldn't happen, but be safe.
2014 size_t Index = 0; 2025 size_t Index = 0;
2015 for (Ice::CfgNode *Node : Func->getNodes()) { 2026 for (Ice::CfgNode *Node : Func->getNodes()) {
2016 if (Node->getInsts().empty()) { 2027 if (Node->getInsts().empty()) {
2017 std::string Buffer; 2028 std::string Buffer;
2018 raw_string_ostream StrBuf(Buffer); 2029 raw_string_ostream StrBuf(Buffer);
2019 StrBuf << "Basic block " << Index << " contains no instructions"; 2030 StrBuf << "Basic block " << Index << " contains no instructions";
(...skipping 1120 matching lines...) Expand 10 before | Expand all | Expand 10 after
3140 } 3151 }
3141 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { 3152 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) {
3142 ErrStream 3153 ErrStream
3143 << IRFilename 3154 << IRFilename
3144 << ": Bitcode stream should be a multiple of 4 bytes in length.\n"; 3155 << ": Bitcode stream should be a multiple of 4 bytes in length.\n";
3145 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); 3156 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes");
3146 } 3157 }
3147 } 3158 }
3148 3159
3149 } // end of namespace Ice 3160 } // 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