Chromium Code Reviews

Side by Side Diff: src/PNaClTranslator.cpp

Issue 545603003: Add branch instructions to Subzero bitcode reader. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix nits in patch set 1. Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
« no previous file with comments | « no previous file | tests_lit/reader_tests/branch.ll » ('j') | 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 // 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 847 matching lines...)
858 raw_string_ostream StrBuf(Buffer); 858 raw_string_ostream StrBuf(Buffer);
859 StrBuf << "Reference to basic block " << Index 859 StrBuf << "Reference to basic block " << Index
860 << " not found. Must be less than " << Nodes.size(); 860 << " not found. Must be less than " << Nodes.size();
861 Error(StrBuf.str()); 861 Error(StrBuf.str());
862 // TODO(kschimpf) Remove error recovery once implementation complete. 862 // TODO(kschimpf) Remove error recovery once implementation complete.
863 Index = 0; 863 Index = 0;
864 } 864 }
865 return Nodes[Index]; 865 return Nodes[Index];
866 } 866 }
867 867
868 // Returns the Index-th basic block in the list of basic blocks.
869 // Assumes Index corresponds to a branch instruction. Hence, if
870 // the branch references the entry block, it also generates a
871 // corresponding error.
872 Ice::CfgNode *getBranchBasicBlock(uint32_t Index) {
873 if (Index == 0) {
874 Error("Branch to entry block not allowed");
875 // TODO(kschimpf) Remove error recovery once implementation complete.
876 }
877 return GetBasicBlock(Index);
878 }
879
868 // Generates the next available local variable using the given 880 // Generates the next available local variable using the given
869 // type. Note: if Ty is void, this function returns NULL. 881 // type. Note: if Ty is void, this function returns NULL.
870 Ice::Variable *NextInstVar(Ice::Type Ty) { 882 Ice::Variable *NextInstVar(Ice::Type Ty) {
871 if (Ty == Ice::IceType_void) 883 if (Ty == Ice::IceType_void)
872 return NULL; 884 return NULL;
873 Ice::Variable *Var = Func->makeVariable(Ty, CurrentNode); 885 Ice::Variable *Var = Func->makeVariable(Ty, CurrentNode);
874 LocalOperands.push_back(Var); 886 LocalOperands.push_back(Var);
875 return Var; 887 return Var;
876 } 888 }
877 889
(...skipping 220 matching lines...)
1098 Ice::CfgNode *Node = *Iter; 1110 Ice::CfgNode *Node = *Iter;
1099 if (Node->getInsts().size() == 0) { 1111 if (Node->getInsts().size() == 0) {
1100 std::string Buffer; 1112 std::string Buffer;
1101 raw_string_ostream StrBuf(Buffer); 1113 raw_string_ostream StrBuf(Buffer);
1102 StrBuf << "Basic block " << Index << " contains no instructions"; 1114 StrBuf << "Basic block " << Index << " contains no instructions";
1103 Error(StrBuf.str()); 1115 Error(StrBuf.str());
1104 // TODO(kschimpf) Remove error recovery once implementation complete. 1116 // TODO(kschimpf) Remove error recovery once implementation complete.
1105 Node->appendInst(Ice::InstUnreachable::create(Func)); 1117 Node->appendInst(Ice::InstUnreachable::create(Func));
1106 } 1118 }
1107 } 1119 }
1108 getTranslator().translateFcn(Func); 1120 // Note: Once any errors have been found, we turn off all
1121 // translation of all remaining functions. This allows use to see
1122 // multiple errors, without adding extra checks to the translator
1123 // for such parsing errors.
1124 if (Context->getNumErrors() == 0)
1125 getTranslator().translateFcn(Func);
1109 } 1126 }
1110 1127
1111 void FunctionParser::ReportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, 1128 void FunctionParser::ReportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op,
1112 Ice::Type OpTy) { 1129 Ice::Type OpTy) {
1113 std::string Buffer; 1130 std::string Buffer;
1114 raw_string_ostream StrBuf(Buffer); 1131 raw_string_ostream StrBuf(Buffer);
1115 StrBuf << "Invalid operator type for " << Ice::InstArithmetic::getOpName(Op) 1132 StrBuf << "Invalid operator type for " << Ice::InstArithmetic::getOpName(Op)
1116 << ". Found " << OpTy; 1133 << ". Found " << OpTy;
1117 Error(StrBuf.str()); 1134 Error(StrBuf.str());
1118 } 1135 }
(...skipping 167 matching lines...)
1286 Error(StrBuf.str()); 1303 Error(StrBuf.str());
1287 } 1304 }
1288 // TODO(kschimpf): Restrict index to a legal constant index (once 1305 // TODO(kschimpf): Restrict index to a legal constant index (once
1289 // constants can be defined). 1306 // constants can be defined).
1290 Ice::Variable *Dest = NextInstVar(EltType); 1307 Ice::Variable *Dest = NextInstVar(EltType);
1291 Inst = Ice::InstInsertElement::create(Func, Dest, Vec, Elt, Index); 1308 Inst = Ice::InstInsertElement::create(Func, Dest, Vec, Elt, Index);
1292 break; 1309 break;
1293 } 1310 }
1294 case naclbitc::FUNC_CODE_INST_RET: { 1311 case naclbitc::FUNC_CODE_INST_RET: {
1295 // RET: [opval?] 1312 // RET: [opval?]
1296 InstIsTerminating = true;
1297 if (!isValidRecordSizeInRange(0, 1, "function block ret")) 1313 if (!isValidRecordSizeInRange(0, 1, "function block ret"))
1298 return; 1314 return;
1299 if (Values.size() == 0) { 1315 if (Values.size() == 0) {
1300 Inst = Ice::InstRet::create(Func); 1316 Inst = Ice::InstRet::create(Func);
1301 } else { 1317 } else {
1302 Inst = Ice::InstRet::create(Func, getRelativeOperand(Values[0])); 1318 Inst = Ice::InstRet::create(Func, getRelativeOperand(Values[0]));
1303 } 1319 }
1320 InstIsTerminating = true;
1321 break;
1322 }
1323 case naclbitc::FUNC_CODE_INST_BR: {
1324 if (Values.size() == 1) {
1325 // BR: [bb#]
1326 Ice::CfgNode *Block = getBranchBasicBlock(Values[0]);
1327 if (Block == NULL)
1328 return;
1329 Inst = Ice::InstBr::create(Func, Block);
1330 } else {
1331 // BR: [bb#, bb#, opval]
1332 if (!isValidRecordSize(3, "function block branch"))
1333 return;
1334 Ice::Operand *Cond = getRelativeOperand(Values[2]);
1335 if (Cond->getType() != Ice::IceType_i1) {
1336 std::string Buffer;
1337 raw_string_ostream StrBuf(Buffer);
1338 StrBuf << "Branch condition not i1";
1339 Error(StrBuf.str());
1340 return;
1341 }
1342 Ice::CfgNode *ThenBlock = getBranchBasicBlock(Values[0]);
1343 Ice::CfgNode *ElseBlock = getBranchBasicBlock(Values[1]);
1344 if (ThenBlock == NULL || ElseBlock == NULL)
1345 return;
1346 Inst = Ice::InstBr::create(Func, Cond, ThenBlock, ElseBlock);
1347 }
1348 InstIsTerminating = true;
1304 break; 1349 break;
1305 } 1350 }
1306 default: 1351 default:
1307 // Generate error message! 1352 // Generate error message!
1308 BlockParserBaseClass::ProcessRecord(); 1353 BlockParserBaseClass::ProcessRecord();
1309 break; 1354 break;
1310 } 1355 }
1311 if (Inst) 1356 if (Inst)
1312 CurrentNode->appendInst(Inst); 1357 CurrentNode->appendInst(Inst);
1313 } 1358 }
(...skipping 156 matching lines...)
1470 if (TopLevelBlocks != 1) { 1515 if (TopLevelBlocks != 1) {
1471 errs() << IRFilename 1516 errs() << IRFilename
1472 << ": Contains more than one module. Found: " << TopLevelBlocks 1517 << ": Contains more than one module. Found: " << TopLevelBlocks
1473 << "\n"; 1518 << "\n";
1474 ErrorStatus = true; 1519 ErrorStatus = true;
1475 } 1520 }
1476 return; 1521 return;
1477 } 1522 }
1478 1523
1479 } // end of namespace Ice 1524 } // end of namespace Ice
OLDNEW
« no previous file with comments | « no previous file | tests_lit/reader_tests/branch.ll » ('j') | no next file with comments »

Powered by Google App Engine