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

Side by Side Diff: src/PNaClTranslator.cpp

Issue 568473002: Add phi instruction to Subzero bitcode reader. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix nits. Created 6 years, 3 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 | tests_lit/reader_tests/phi.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 805 matching lines...) Expand 10 before | Expand all | Expand 10 after
816 CachedNumGlobalValueIDs(Context->getNumGlobalValueIDs()), 816 CachedNumGlobalValueIDs(Context->getNumGlobalValueIDs()),
817 InstIsTerminating(false) { 817 InstIsTerminating(false) {
818 Func->setFunctionName(LLVMFunc->getName()); 818 Func->setFunctionName(LLVMFunc->getName());
819 Func->setReturnType(Context->convertToIceType(LLVMFunc->getReturnType())); 819 Func->setReturnType(Context->convertToIceType(LLVMFunc->getReturnType()));
820 Func->setInternal(LLVMFunc->hasInternalLinkage()); 820 Func->setInternal(LLVMFunc->hasInternalLinkage());
821 CurrentNode = InstallNextBasicBlock(); 821 CurrentNode = InstallNextBasicBlock();
822 Func->setEntryNode(CurrentNode); 822 Func->setEntryNode(CurrentNode);
823 for (Function::const_arg_iterator ArgI = LLVMFunc->arg_begin(), 823 for (Function::const_arg_iterator ArgI = LLVMFunc->arg_begin(),
824 ArgE = LLVMFunc->arg_end(); 824 ArgE = LLVMFunc->arg_end();
825 ArgI != ArgE; ++ArgI) { 825 ArgI != ArgE; ++ArgI) {
826 Func->addArg(NextInstVar(Context->convertToIceType(ArgI->getType()))); 826 Func->addArg(getNextInstVar(Context->convertToIceType(ArgI->getType())));
827 } 827 }
828 } 828 }
829 829
830 ~FunctionParser() LLVM_OVERRIDE; 830 ~FunctionParser() LLVM_OVERRIDE;
831 831
832 // Set the next constant ID to the given constant C. 832 // Set the next constant ID to the given constant C.
833 void setNextConstantID(Ice::Constant *C) { LocalOperands.push_back(C); } 833 void setNextConstantID(Ice::Constant *C) { LocalOperands.push_back(C); }
834 834
835 private: 835 private:
836 // Timer for reading function bitcode and converting to ICE. 836 // Timer for reading function bitcode and converting to ICE.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
877 virtual bool ParseBlock(unsigned BlockID) LLVM_OVERRIDE; 877 virtual bool ParseBlock(unsigned BlockID) LLVM_OVERRIDE;
878 878
879 virtual void ProcessRecord() LLVM_OVERRIDE; 879 virtual void ProcessRecord() LLVM_OVERRIDE;
880 880
881 virtual void ExitBlock() LLVM_OVERRIDE; 881 virtual void ExitBlock() LLVM_OVERRIDE;
882 882
883 // Creates and appends a new basic block to the list of basic blocks. 883 // Creates and appends a new basic block to the list of basic blocks.
884 Ice::CfgNode *InstallNextBasicBlock() { return Func->makeNode(); } 884 Ice::CfgNode *InstallNextBasicBlock() { return Func->makeNode(); }
885 885
886 // Returns the Index-th basic block in the list of basic blocks. 886 // Returns the Index-th basic block in the list of basic blocks.
887 Ice::CfgNode *GetBasicBlock(uint32_t Index) { 887 Ice::CfgNode *getBasicBlock(uint32_t Index) {
888 const Ice::NodeList &Nodes = Func->getNodes(); 888 const Ice::NodeList &Nodes = Func->getNodes();
889 if (Index >= Nodes.size()) { 889 if (Index >= Nodes.size()) {
890 std::string Buffer; 890 std::string Buffer;
891 raw_string_ostream StrBuf(Buffer); 891 raw_string_ostream StrBuf(Buffer);
892 StrBuf << "Reference to basic block " << Index 892 StrBuf << "Reference to basic block " << Index
893 << " not found. Must be less than " << Nodes.size(); 893 << " not found. Must be less than " << Nodes.size();
894 Error(StrBuf.str()); 894 Error(StrBuf.str());
895 // TODO(kschimpf) Remove error recovery once implementation complete. 895 // TODO(kschimpf) Remove error recovery once implementation complete.
896 Index = 0; 896 Index = 0;
897 } 897 }
898 return Nodes[Index]; 898 return Nodes[Index];
899 } 899 }
900 900
901 // Returns the Index-th basic block in the list of basic blocks. 901 // Returns the Index-th basic block in the list of basic blocks.
902 // Assumes Index corresponds to a branch instruction. Hence, if 902 // Assumes Index corresponds to a branch instruction. Hence, if
903 // the branch references the entry block, it also generates a 903 // the branch references the entry block, it also generates a
904 // corresponding error. 904 // corresponding error.
905 Ice::CfgNode *getBranchBasicBlock(uint32_t Index) { 905 Ice::CfgNode *getBranchBasicBlock(uint32_t Index) {
906 if (Index == 0) { 906 if (Index == 0) {
907 Error("Branch to entry block not allowed"); 907 Error("Branch to entry block not allowed");
908 // TODO(kschimpf) Remove error recovery once implementation complete. 908 // TODO(kschimpf) Remove error recovery once implementation complete.
909 } 909 }
910 return GetBasicBlock(Index); 910 return getBasicBlock(Index);
911 } 911 }
912 912
913 // Generates the next available local variable using the given 913 // Generates the next available local variable using the given type.
914 // type. Note: if Ty is void, this function returns NULL. 914 Ice::Variable *getNextInstVar(Ice::Type Ty) {
915 Ice::Variable *NextInstVar(Ice::Type Ty) { 915 if (Ty == Ice::IceType_void) {
916 if (Ty == Ice::IceType_void) 916 Error("Can't define instruction value using type void");
917 return NULL; 917 // Recover since we can't throw an exception.
918 Ty = Ice::IceType_i32;
919 }
918 Ice::Variable *Var = Func->makeVariable(Ty, CurrentNode); 920 Ice::Variable *Var = Func->makeVariable(Ty, CurrentNode);
919 LocalOperands.push_back(Var); 921 LocalOperands.push_back(Var);
920 return Var; 922 return Var;
921 } 923 }
922 924
923 // Converts a relative index (to the next instruction to be read) to 925 // Converts a relative index (wrt to BaseIndex) to an absolute value
924 // an absolute value index. 926 // index.
925 uint32_t convertRelativeToAbsIndex(int32_t Id) { 927 uint32_t convertRelativeToAbsIndex(int32_t Id, int32_t BaseIndex) {
926 int32_t AbsNextId = CachedNumGlobalValueIDs + LocalOperands.size(); 928 if (BaseIndex < Id) {
927 if (Id > 0 && AbsNextId < Id) {
928 std::string Buffer; 929 std::string Buffer;
929 raw_string_ostream StrBuf(Buffer); 930 raw_string_ostream StrBuf(Buffer);
930 StrBuf << "Invalid relative value id: " << Id 931 StrBuf << "Invalid relative value id: " << Id
931 << " (must be <= " << AbsNextId << ")"; 932 << " (must be <= " << BaseIndex << ")";
932 Error(StrBuf.str()); 933 Error(StrBuf.str());
933 // TODO(kschimpf) Remove error recovery once implementation complete. 934 // TODO(kschimpf) Remove error recovery once implementation complete.
934 return 0; 935 return 0;
935 } 936 }
936 return AbsNextId - Id; 937 return BaseIndex - Id;
937 } 938 }
938 939
939 // Returns the value referenced by the given value Index. 940 // Returns the value referenced by the given value Index.
940 Ice::Operand *getOperand(uint32_t Index) { 941 Ice::Operand *getOperand(uint32_t Index) {
941 if (Index < CachedNumGlobalValueIDs) { 942 if (Index < CachedNumGlobalValueIDs) {
942 // TODO(kschimpf): Define implementation. 943 // TODO(kschimpf): Define implementation.
943 report_fatal_error("getOperand of global addresses not implemented"); 944 report_fatal_error("getOperand of global addresses not implemented");
944 } 945 }
945 uint32_t LocalIndex = Index - CachedNumGlobalValueIDs; 946 uint32_t LocalIndex = Index - CachedNumGlobalValueIDs;
946 if (LocalIndex >= LocalOperands.size()) { 947 if (LocalIndex >= LocalOperands.size()) {
947 std::string Buffer; 948 std::string Buffer;
948 raw_string_ostream StrBuf(Buffer); 949 raw_string_ostream StrBuf(Buffer);
949 StrBuf << "Value index " << Index << " out of range. Must be less than " 950 StrBuf << "Value index " << Index << " out of range. Must be less than "
950 << (LocalOperands.size() + CachedNumGlobalValueIDs); 951 << (LocalOperands.size() + CachedNumGlobalValueIDs);
951 Error(StrBuf.str()); 952 Error(StrBuf.str());
952 report_fatal_error("Unable to continue"); 953 report_fatal_error("Unable to continue");
953 } 954 }
954 return LocalOperands[LocalIndex]; 955 return LocalOperands[LocalIndex];
955 } 956 }
956 957
957 // Returns the relative operand (wrt to next instruction) referenced by 958 // Returns the relative operand (wrt to BaseIndex) referenced by
958 // the given value index. 959 // the given value Index.
959 Ice::Operand *getRelativeOperand(uint32_t Index) { 960 Ice::Operand *getRelativeOperand(int32_t Index, int32_t BaseIndex) {
960 return getOperand(convertRelativeToAbsIndex(Index)); 961 return getOperand(convertRelativeToAbsIndex(Index, BaseIndex));
962 }
963
964 // Returns the absolute index of the next value generating instruction.
965 uint32_t getNextInstIndex() const {
966 return CachedNumGlobalValueIDs + LocalOperands.size();
961 } 967 }
962 968
963 // Generates type error message for binary operator Op 969 // Generates type error message for binary operator Op
964 // operating on Type OpTy. 970 // operating on Type OpTy.
965 void ReportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy); 971 void ReportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy);
966 972
967 // Validates if integer logical Op, for type OpTy, is valid. 973 // Validates if integer logical Op, for type OpTy, is valid.
968 // Returns true if valid. Otherwise generates error message and 974 // Returns true if valid. Otherwise generates error message and
969 // returns false. 975 // returns false.
970 bool isValidIntegerLogicalOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) { 976 bool isValidIntegerLogicalOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
1309 raw_string_ostream StrBuf(Buffer); 1315 raw_string_ostream StrBuf(Buffer);
1310 StrBuf << "Invalid operator type for " << Ice::InstArithmetic::getOpName(Op) 1316 StrBuf << "Invalid operator type for " << Ice::InstArithmetic::getOpName(Op)
1311 << ". Found " << OpTy; 1317 << ". Found " << OpTy;
1312 Error(StrBuf.str()); 1318 Error(StrBuf.str());
1313 } 1319 }
1314 1320
1315 void FunctionParser::ProcessRecord() { 1321 void FunctionParser::ProcessRecord() {
1316 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); 1322 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1317 if (InstIsTerminating) { 1323 if (InstIsTerminating) {
1318 InstIsTerminating = false; 1324 InstIsTerminating = false;
1319 CurrentNode = GetBasicBlock(++CurrentBbIndex); 1325 CurrentNode = getBasicBlock(++CurrentBbIndex);
1320 } 1326 }
1321 Ice::Inst *Inst = NULL; 1327 // The base index for relative indexing.
1328 int32_t BaseIndex = getNextInstIndex();
1322 switch (Record.GetCode()) { 1329 switch (Record.GetCode()) {
1323 case naclbitc::FUNC_CODE_DECLAREBLOCKS: { 1330 case naclbitc::FUNC_CODE_DECLAREBLOCKS: {
1324 // DECLAREBLOCKS: [n] 1331 // DECLAREBLOCKS: [n]
1325 if (!isValidRecordSize(1, "function block count")) 1332 if (!isValidRecordSize(1, "function block count"))
1326 return; 1333 return;
1327 if (Func->getNodes().size() != 1) { 1334 if (Func->getNodes().size() != 1) {
1328 Error("Duplicate function block count record"); 1335 Error("Duplicate function block count record");
1329 return; 1336 return;
1330 } 1337 }
1331 uint32_t NumBbs = Values[0]; 1338 uint32_t NumBbs = Values[0];
1332 if (NumBbs == 0) { 1339 if (NumBbs == 0) {
1333 Error("Functions must contain at least one basic block."); 1340 Error("Functions must contain at least one basic block.");
1334 // TODO(kschimpf) Remove error recovery once implementation complete. 1341 // TODO(kschimpf) Remove error recovery once implementation complete.
1335 NumBbs = 1; 1342 NumBbs = 1;
1336 } 1343 }
1337 // Install the basic blocks, skipping bb0 which was created in the 1344 // Install the basic blocks, skipping bb0 which was created in the
1338 // constructor. 1345 // constructor.
1339 for (size_t i = 1; i < NumBbs; ++i) 1346 for (size_t i = 1; i < NumBbs; ++i)
1340 InstallNextBasicBlock(); 1347 InstallNextBasicBlock();
1341 break; 1348 break;
1342 } 1349 }
1343 case naclbitc::FUNC_CODE_INST_BINOP: { 1350 case naclbitc::FUNC_CODE_INST_BINOP: {
1344 // BINOP: [opval, opval, opcode] 1351 // BINOP: [opval, opval, opcode]
1345 if (!isValidRecordSize(3, "function block binop")) 1352 if (!isValidRecordSize(3, "function block binop"))
1346 return; 1353 return;
1347 Ice::Operand *Op1 = getRelativeOperand(Values[0]); 1354 Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex);
1348 Ice::Operand *Op2 = getRelativeOperand(Values[1]); 1355 Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex);
1349 Ice::Type Type1 = Op1->getType(); 1356 Ice::Type Type1 = Op1->getType();
1350 Ice::Type Type2 = Op2->getType(); 1357 Ice::Type Type2 = Op2->getType();
1351 if (Type1 != Type2) { 1358 if (Type1 != Type2) {
1352 std::string Buffer; 1359 std::string Buffer;
1353 raw_string_ostream StrBuf(Buffer); 1360 raw_string_ostream StrBuf(Buffer);
1354 StrBuf << "Binop argument types differ: " << Type1 << " and " << Type2; 1361 StrBuf << "Binop argument types differ: " << Type1 << " and " << Type2;
1355 Error(StrBuf.str()); 1362 Error(StrBuf.str());
1356 // TODO(kschimpf) Remove error recovery once implementation complete. 1363 // TODO(kschimpf) Remove error recovery once implementation complete.
1357 Op2 = Op1; 1364 Op2 = Op1;
1358 } 1365 }
1359 1366
1360 Ice::InstArithmetic::OpKind Opcode; 1367 Ice::InstArithmetic::OpKind Opcode;
1361 if (!convertBinopOpcode(Values[2], Type1, Opcode)) 1368 if (!convertBinopOpcode(Values[2], Type1, Opcode))
1362 return; 1369 return;
1363 Ice::Variable *Dest = NextInstVar(Type1); 1370 CurrentNode->appendInst(
1364 Inst = Ice::InstArithmetic::create(Func, Opcode, Dest, Op1, Op2); 1371 Ice::InstArithmetic::create(
1372 Func, Opcode, getNextInstVar(Type1), Op1, Op2));
1365 break; 1373 break;
1366 } 1374 }
1367 case naclbitc::FUNC_CODE_INST_CAST: { 1375 case naclbitc::FUNC_CODE_INST_CAST: {
1368 // CAST: [opval, destty, castopc] 1376 // CAST: [opval, destty, castopc]
1369 if (!isValidRecordSize(3, "function block cast")) 1377 if (!isValidRecordSize(3, "function block cast"))
1370 return; 1378 return;
1371 Ice::Operand *Src = getRelativeOperand(Values[0]); 1379 Ice::Operand *Src = getRelativeOperand(Values[0], BaseIndex);
1372 Type *CastType = Context->getTypeByID(Values[1]); 1380 Type *CastType = Context->getTypeByID(Values[1]);
1373 Instruction::CastOps LLVMCastOp; 1381 Instruction::CastOps LLVMCastOp;
1374 Ice::InstCast::OpKind CastKind; 1382 Ice::InstCast::OpKind CastKind;
1375 if (!naclbitc::DecodeCastOpcode(Values[2], LLVMCastOp) || 1383 if (!naclbitc::DecodeCastOpcode(Values[2], LLVMCastOp) ||
1376 !convertLLVMCastOpToIceOp(LLVMCastOp, CastKind)) { 1384 !convertLLVMCastOpToIceOp(LLVMCastOp, CastKind)) {
1377 std::string Buffer; 1385 std::string Buffer;
1378 raw_string_ostream StrBuf(Buffer); 1386 raw_string_ostream StrBuf(Buffer);
1379 StrBuf << "Cast opcode not understood: " << Values[2]; 1387 StrBuf << "Cast opcode not understood: " << Values[2];
1380 Error(StrBuf.str()); 1388 Error(StrBuf.str());
1381 return; 1389 return;
1382 } 1390 }
1383 Type *SrcType = Context->convertToLLVMType(Src->getType()); 1391 Type *SrcType = Context->convertToLLVMType(Src->getType());
1384 if (!CastInst::castIsValid(LLVMCastOp, SrcType, CastType)) { 1392 if (!CastInst::castIsValid(LLVMCastOp, SrcType, CastType)) {
1385 std::string Buffer; 1393 std::string Buffer;
1386 raw_string_ostream StrBuf(Buffer); 1394 raw_string_ostream StrBuf(Buffer);
1387 StrBuf << "Illegal cast: " << Instruction::getOpcodeName(LLVMCastOp) 1395 StrBuf << "Illegal cast: " << Instruction::getOpcodeName(LLVMCastOp)
1388 << " " << *SrcType << " to " << *CastType; 1396 << " " << *SrcType << " to " << *CastType;
1389 Error(StrBuf.str()); 1397 Error(StrBuf.str());
1390 return; 1398 return;
1391 } 1399 }
1392 Ice::Variable *Dest = NextInstVar(Context->convertToIceType(CastType)); 1400 CurrentNode->appendInst(
1393 Inst = Ice::InstCast::create(Func, CastKind, Dest, Src); 1401 Ice::InstCast::create(
1402 Func, CastKind, getNextInstVar(Context->convertToIceType(CastType)),
1403 Src));
1394 break; 1404 break;
1395 } 1405 }
1396 case naclbitc::FUNC_CODE_INST_VSELECT: { 1406 case naclbitc::FUNC_CODE_INST_VSELECT: {
1397 // VSELECT: [opval, opval, pred] 1407 // VSELECT: [opval, opval, pred]
1398 Ice::Operand *ThenVal = getOperand(convertRelativeToAbsIndex(Values[0])); 1408 Ice::Operand *ThenVal = getRelativeOperand(Values[0], BaseIndex);
1399 Ice::Type ThenType = ThenVal->getType(); 1409 Ice::Type ThenType = ThenVal->getType();
1400 Ice::Operand *ElseVal = getOperand(convertRelativeToAbsIndex(Values[1])); 1410 Ice::Operand *ElseVal = getRelativeOperand(Values[1], BaseIndex);
1401 Ice::Type ElseType = ElseVal->getType(); 1411 Ice::Type ElseType = ElseVal->getType();
1402 if (ThenType != ElseType) { 1412 if (ThenType != ElseType) {
1403 std::string Buffer; 1413 std::string Buffer;
1404 raw_string_ostream StrBuf(Buffer); 1414 raw_string_ostream StrBuf(Buffer);
1405 StrBuf << "Select operands not same type. Found " << ThenType << " and " 1415 StrBuf << "Select operands not same type. Found " << ThenType << " and "
1406 << ElseType; 1416 << ElseType;
1407 Error(StrBuf.str()); 1417 Error(StrBuf.str());
1408 return; 1418 return;
1409 } 1419 }
1410 Ice::Operand *CondVal = getOperand(convertRelativeToAbsIndex(Values[2])); 1420 Ice::Operand *CondVal = getRelativeOperand(Values[2], BaseIndex);
1411 Ice::Type CondType = CondVal->getType(); 1421 Ice::Type CondType = CondVal->getType();
1412 if (isVectorType(CondType)) { 1422 if (isVectorType(CondType)) {
1413 if (!isVectorType(ThenType) || 1423 if (!isVectorType(ThenType) ||
1414 typeElementType(CondType) != Ice::IceType_i1 || 1424 typeElementType(CondType) != Ice::IceType_i1 ||
1415 typeNumElements(ThenType) != typeNumElements(CondType)) { 1425 typeNumElements(ThenType) != typeNumElements(CondType)) {
1416 std::string Buffer; 1426 std::string Buffer;
1417 raw_string_ostream StrBuf(Buffer); 1427 raw_string_ostream StrBuf(Buffer);
1418 StrBuf << "Select condition " << CondType 1428 StrBuf << "Select condition " << CondType
1419 << " not allowed for values of type " << ThenType; 1429 << " not allowed for values of type " << ThenType;
1420 Error(StrBuf.str()); 1430 Error(StrBuf.str());
1421 return; 1431 return;
1422 } 1432 }
1423 } else if (CondVal->getType() != Ice::IceType_i1) { 1433 } else if (CondVal->getType() != Ice::IceType_i1) {
1424 std::string Buffer; 1434 std::string Buffer;
1425 raw_string_ostream StrBuf(Buffer); 1435 raw_string_ostream StrBuf(Buffer);
1426 StrBuf << "Select condition not type i1. Found: " << CondVal->getType(); 1436 StrBuf << "Select condition not type i1. Found: " << CondVal->getType();
1427 Error(StrBuf.str()); 1437 Error(StrBuf.str());
1428 return; 1438 return;
1429 } 1439 }
1430 Ice::Variable *DestVal = NextInstVar(ThenType); 1440 CurrentNode->appendInst(
1431 Inst = Ice::InstSelect::create(Func, DestVal, CondVal, ThenVal, ElseVal); 1441 Ice::InstSelect::create(
1442 Func, getNextInstVar(ThenType), CondVal, ThenVal, ElseVal));
1432 break; 1443 break;
1433 } 1444 }
1434 case naclbitc::FUNC_CODE_INST_EXTRACTELT: { 1445 case naclbitc::FUNC_CODE_INST_EXTRACTELT: {
1435 // EXTRACTELT: [opval, opval] 1446 // EXTRACTELT: [opval, opval]
1436 if (!isValidRecordSize(2, "function block extract element")) 1447 if (!isValidRecordSize(2, "function block extract element"))
1437 return; 1448 return;
1438 Ice::Operand *Vec = getRelativeOperand(Values[0]); 1449 Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex);
1439 Ice::Type VecType = Vec->getType(); 1450 Ice::Type VecType = Vec->getType();
1440 if (!Ice::isVectorType(VecType)) { 1451 if (!Ice::isVectorType(VecType)) {
1441 std::string Buffer; 1452 std::string Buffer;
1442 raw_string_ostream StrBuf(Buffer); 1453 raw_string_ostream StrBuf(Buffer);
1443 StrBuf << "Extractelement not on vector. Found: " << Vec; 1454 StrBuf << "Extractelement not on vector. Found: " << Vec;
1444 Error(StrBuf.str()); 1455 Error(StrBuf.str());
1445 } 1456 }
1446 Ice::Operand *Index = getRelativeOperand(Values[1]); 1457 Ice::Operand *Index = getRelativeOperand(Values[1], BaseIndex);
1447 if (Index->getType() != Ice::IceType_i32) { 1458 if (Index->getType() != Ice::IceType_i32) {
1448 std::string Buffer; 1459 std::string Buffer;
1449 raw_string_ostream StrBuf(Buffer); 1460 raw_string_ostream StrBuf(Buffer);
1450 StrBuf << "Extractelement index not i32. Found: " << Index; 1461 StrBuf << "Extractelement index not i32. Found: " << Index;
1451 Error(StrBuf.str()); 1462 Error(StrBuf.str());
1452 } 1463 }
1453 // TODO(kschimpf): Restrict index to a legal constant index (once 1464 // TODO(kschimpf): Restrict index to a legal constant index (once
1454 // constants can be defined). 1465 // constants can be defined).
1455 Ice::Variable *Dest = NextInstVar(typeElementType(VecType)); 1466 CurrentNode->appendInst(
1456 Inst = Ice::InstExtractElement::create(Func, Dest, Vec, Index); 1467 Ice::InstExtractElement::create(
1468 Func, getNextInstVar(typeElementType(VecType)), Vec, Index));
1457 break; 1469 break;
1458 } 1470 }
1459 case naclbitc::FUNC_CODE_INST_INSERTELT: { 1471 case naclbitc::FUNC_CODE_INST_INSERTELT: {
1460 // INSERTELT: [opval, opval, opval] 1472 // INSERTELT: [opval, opval, opval]
1461 if (!isValidRecordSize(3, "function block insert element")) 1473 if (!isValidRecordSize(3, "function block insert element"))
1462 return; 1474 return;
1463 Ice::Operand *Vec = getRelativeOperand(Values[0]); 1475 Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex);
1464 Ice::Type VecType = Vec->getType(); 1476 Ice::Type VecType = Vec->getType();
1465 if (!Ice::isVectorType(VecType)) { 1477 if (!Ice::isVectorType(VecType)) {
1466 std::string Buffer; 1478 std::string Buffer;
1467 raw_string_ostream StrBuf(Buffer); 1479 raw_string_ostream StrBuf(Buffer);
1468 StrBuf << "Insertelement not on vector. Found: " << Vec; 1480 StrBuf << "Insertelement not on vector. Found: " << Vec;
1469 Error(StrBuf.str()); 1481 Error(StrBuf.str());
1470 } 1482 }
1471 Ice::Operand *Elt = getRelativeOperand(Values[1]); 1483 Ice::Operand *Elt = getRelativeOperand(Values[1], BaseIndex);
1472 Ice::Type EltType = Elt->getType(); 1484 Ice::Type EltType = Elt->getType();
1473 if (EltType != typeElementType(VecType)) { 1485 if (EltType != typeElementType(VecType)) {
1474 std::string Buffer; 1486 std::string Buffer;
1475 raw_string_ostream StrBuf(Buffer); 1487 raw_string_ostream StrBuf(Buffer);
1476 StrBuf << "Insertelement element not " << typeElementType(VecType) 1488 StrBuf << "Insertelement element not " << typeElementType(VecType)
1477 << ". Found: " << Elt; 1489 << ". Found: " << Elt;
1478 Error(StrBuf.str()); 1490 Error(StrBuf.str());
1479 } 1491 }
1480 Ice::Operand *Index = getRelativeOperand(Values[2]); 1492 Ice::Operand *Index = getRelativeOperand(Values[2], BaseIndex);
1481 if (Index->getType() != Ice::IceType_i32) { 1493 if (Index->getType() != Ice::IceType_i32) {
1482 std::string Buffer; 1494 std::string Buffer;
1483 raw_string_ostream StrBuf(Buffer); 1495 raw_string_ostream StrBuf(Buffer);
1484 StrBuf << "Insertelement index not i32. Found: " << Index; 1496 StrBuf << "Insertelement index not i32. Found: " << Index;
1485 Error(StrBuf.str()); 1497 Error(StrBuf.str());
1486 } 1498 }
1487 // TODO(kschimpf): Restrict index to a legal constant index (once 1499 // TODO(kschimpf): Restrict index to a legal constant index (once
1488 // constants can be defined). 1500 // constants can be defined).
1489 Ice::Variable *Dest = NextInstVar(EltType); 1501 CurrentNode->appendInst(
1490 Inst = Ice::InstInsertElement::create(Func, Dest, Vec, Elt, Index); 1502 Ice::InstInsertElement::create(
1503 Func, getNextInstVar(EltType), Vec, Elt, Index));
1491 break; 1504 break;
1492 } 1505 }
1493 case naclbitc::FUNC_CODE_INST_CMP2: { 1506 case naclbitc::FUNC_CODE_INST_CMP2: {
1494 // CMP2: [opval, opval, pred] 1507 // CMP2: [opval, opval, pred]
1495 if (!isValidRecordSize(3, "function block compare")) 1508 if (!isValidRecordSize(3, "function block compare"))
1496 return; 1509 return;
1497 Ice::Operand *Op1 = getRelativeOperand(Values[0]); 1510 Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex);
1498 Ice::Operand *Op2 = getRelativeOperand(Values[1]); 1511 Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex);
1499 Ice::Type Op1Type = Op1->getType(); 1512 Ice::Type Op1Type = Op1->getType();
1500 Ice::Type Op2Type = Op2->getType(); 1513 Ice::Type Op2Type = Op2->getType();
1501 if (Op1Type != Op2Type) { 1514 if (Op1Type != Op2Type) {
1502 std::string Buffer; 1515 std::string Buffer;
1503 raw_string_ostream StrBuf(Buffer); 1516 raw_string_ostream StrBuf(Buffer);
1504 StrBuf << "Compare argument types differ: " << Op1Type 1517 StrBuf << "Compare argument types differ: " << Op1Type
1505 << " and " << Op2Type; 1518 << " and " << Op2Type;
1506 Error(StrBuf.str()); 1519 Error(StrBuf.str());
1507 // TODO(kschimpf) Remove error recovery once implementation complete. 1520 // TODO(kschimpf) Remove error recovery once implementation complete.
1508 Op2 = Op1; 1521 Op2 = Op1;
1509 } 1522 }
1510 Ice::Type DestType = getCompareResultType(Op1Type); 1523 Ice::Type DestType = getCompareResultType(Op1Type);
1511 if (DestType == Ice::IceType_void) { 1524 if (DestType == Ice::IceType_void) {
1512 std::string Buffer; 1525 std::string Buffer;
1513 raw_string_ostream StrBuf(Buffer); 1526 raw_string_ostream StrBuf(Buffer);
1514 StrBuf << "Compare not defined for type " << Op1Type; 1527 StrBuf << "Compare not defined for type " << Op1Type;
1515 Error(StrBuf.str()); 1528 Error(StrBuf.str());
1516 return; 1529 return;
1517 } 1530 }
1518 Ice::Variable *Dest = NextInstVar(DestType); 1531 Ice::Variable *Dest = getNextInstVar(DestType);
1519 if (isIntegerType(Op1Type)) { 1532 if (isIntegerType(Op1Type)) {
1520 Ice::InstIcmp::ICond Cond; 1533 Ice::InstIcmp::ICond Cond;
1521 if (!convertNaClBitcICmpOpToIce(Values[2], Cond)) { 1534 if (!convertNaClBitcICmpOpToIce(Values[2], Cond)) {
1522 std::string Buffer; 1535 std::string Buffer;
1523 raw_string_ostream StrBuf(Buffer); 1536 raw_string_ostream StrBuf(Buffer);
1524 StrBuf << "Compare record contains unknown integer predicate index: " 1537 StrBuf << "Compare record contains unknown integer predicate index: "
1525 << Values[2]; 1538 << Values[2];
1526 Error(StrBuf.str()); 1539 Error(StrBuf.str());
1527 // TODO(kschimpf) Remove error recovery once implementation complete. 1540 // TODO(kschimpf) Remove error recovery once implementation complete.
1528 Cond = Ice::InstIcmp::Eq; 1541 Cond = Ice::InstIcmp::Eq;
1529 } 1542 }
1530 Inst = Ice::InstIcmp::create(Func, Cond, Dest, Op1, Op2); 1543 CurrentNode->appendInst(
1544 Ice::InstIcmp::create(Func, Cond, Dest, Op1, Op2));
1531 } else if (isFloatingType(Op1Type)){ 1545 } else if (isFloatingType(Op1Type)){
1532 Ice::InstFcmp::FCond Cond; 1546 Ice::InstFcmp::FCond Cond;
1533 if (!convertNaClBitcFCompOpToIce(Values[2], Cond)) { 1547 if (!convertNaClBitcFCompOpToIce(Values[2], Cond)) {
1534 std::string Buffer; 1548 std::string Buffer;
1535 raw_string_ostream StrBuf(Buffer); 1549 raw_string_ostream StrBuf(Buffer);
1536 StrBuf << "Compare record contains unknown float predicate index: " 1550 StrBuf << "Compare record contains unknown float predicate index: "
1537 << Values[2]; 1551 << Values[2];
1538 Error(StrBuf.str()); 1552 Error(StrBuf.str());
1539 // TODO(kschimpf) Remove error recovery once implementation complete. 1553 // TODO(kschimpf) Remove error recovery once implementation complete.
1540 Cond = Ice::InstFcmp::False; 1554 Cond = Ice::InstFcmp::False;
1541 } 1555 }
1542 Inst = Ice::InstFcmp::create(Func, Cond, Dest, Op1, Op2); 1556 CurrentNode->appendInst(
1557 Ice::InstFcmp::create(Func, Cond, Dest, Op1, Op2));
1543 } else { 1558 } else {
1544 // Not sure this can happen, but be safe. 1559 // Not sure this can happen, but be safe.
1545 std::string Buffer; 1560 std::string Buffer;
1546 raw_string_ostream StrBuf(Buffer); 1561 raw_string_ostream StrBuf(Buffer);
1547 StrBuf << "Compare on type not understood: " << Op1Type; 1562 StrBuf << "Compare on type not understood: " << Op1Type;
1548 Error(StrBuf.str()); 1563 Error(StrBuf.str());
1549 return; 1564 return;
1550 } 1565 }
1551 break; 1566 break;
1552 } 1567 }
1553 case naclbitc::FUNC_CODE_INST_RET: { 1568 case naclbitc::FUNC_CODE_INST_RET: {
1554 // RET: [opval?] 1569 // RET: [opval?]
1555 if (!isValidRecordSizeInRange(0, 1, "function block ret")) 1570 if (!isValidRecordSizeInRange(0, 1, "function block ret"))
1556 return; 1571 return;
1557 if (Values.size() == 0) { 1572 if (Values.size() == 0) {
1558 Inst = Ice::InstRet::create(Func); 1573 CurrentNode->appendInst(Ice::InstRet::create(Func));
1559 } else { 1574 } else {
1560 Inst = Ice::InstRet::create(Func, getRelativeOperand(Values[0])); 1575 CurrentNode->appendInst(
1576 Ice::InstRet::create(Func, getRelativeOperand(Values[0], BaseIndex)));
1561 } 1577 }
1562 InstIsTerminating = true; 1578 InstIsTerminating = true;
1563 break; 1579 break;
1564 } 1580 }
1565 case naclbitc::FUNC_CODE_INST_BR: { 1581 case naclbitc::FUNC_CODE_INST_BR: {
1566 if (Values.size() == 1) { 1582 if (Values.size() == 1) {
1567 // BR: [bb#] 1583 // BR: [bb#]
1568 Ice::CfgNode *Block = getBranchBasicBlock(Values[0]); 1584 Ice::CfgNode *Block = getBranchBasicBlock(Values[0]);
1569 if (Block == NULL) 1585 if (Block == NULL)
1570 return; 1586 return;
1571 Inst = Ice::InstBr::create(Func, Block); 1587 CurrentNode->appendInst(Ice::InstBr::create(Func, Block));
1572 } else { 1588 } else {
1573 // BR: [bb#, bb#, opval] 1589 // BR: [bb#, bb#, opval]
1574 if (!isValidRecordSize(3, "function block branch")) 1590 if (!isValidRecordSize(3, "function block branch"))
1575 return; 1591 return;
1576 Ice::Operand *Cond = getRelativeOperand(Values[2]); 1592 Ice::Operand *Cond = getRelativeOperand(Values[2], BaseIndex);
1577 if (Cond->getType() != Ice::IceType_i1) { 1593 if (Cond->getType() != Ice::IceType_i1) {
1578 std::string Buffer; 1594 std::string Buffer;
1579 raw_string_ostream StrBuf(Buffer); 1595 raw_string_ostream StrBuf(Buffer);
1580 StrBuf << "Branch condition not i1"; 1596 StrBuf << "Branch condition not i1";
1581 Error(StrBuf.str()); 1597 Error(StrBuf.str());
1582 return; 1598 return;
1583 } 1599 }
1584 Ice::CfgNode *ThenBlock = getBranchBasicBlock(Values[0]); 1600 Ice::CfgNode *ThenBlock = getBranchBasicBlock(Values[0]);
1585 Ice::CfgNode *ElseBlock = getBranchBasicBlock(Values[1]); 1601 Ice::CfgNode *ElseBlock = getBranchBasicBlock(Values[1]);
1586 if (ThenBlock == NULL || ElseBlock == NULL) 1602 if (ThenBlock == NULL || ElseBlock == NULL)
1587 return; 1603 return;
1588 Inst = Ice::InstBr::create(Func, Cond, ThenBlock, ElseBlock); 1604 CurrentNode->appendInst(
1605 Ice::InstBr::create(Func, Cond, ThenBlock, ElseBlock));
1589 } 1606 }
1590 InstIsTerminating = true; 1607 InstIsTerminating = true;
1591 break; 1608 break;
1592 } 1609 }
1610 case naclbitc::FUNC_CODE_INST_PHI: {
1611 // PHI: [ty, val0,bb0, ...]
jvoung (off chromium) 2014/09/11 19:14:43 add a space between val0, bb0 ?
Jim Stichnoth 2014/09/11 19:31:29 I assumed that was intentional grouping, e.g. [t
Karl 2014/09/11 21:43:04 Actually, the space probably be added. Clarifying
1612 if (!isValidRecordSizeAtLeast(3, "function block phi"))
1613 return;
1614 if ((Values.size() & 0x1) == 0) {
1615 // Not an odd number of values.
1616 std::string Buffer;
1617 raw_string_ostream StrBuf(Buffer);
1618 StrBuf << "function block phi record size not valid: " << Values.size();
1619 Error(StrBuf.str());
1620 return;
1621 }
1622 unsigned NumValues = Values.size()/2;
Jim Stichnoth 2014/09/11 18:26:40 Maybe use "Values.size() >> 1" to make it a little
Karl 2014/09/11 21:43:04 Done.
1623 Ice::Type Ty = Context->convertToIceType(Context->getTypeByID(Values[0]));
1624 if (Ty == Ice::IceType_void) {
1625 Error("Phi record using type void not allowed");
1626 return;
1627 }
1628 Ice::Variable *Dest = getNextInstVar(Ty);
1629 Ice::InstPhi *Phi =
1630 Ice::InstPhi::create(Func, NumValues, Dest);
1631 for (unsigned i = 1, e = Values.size(); i < e; i += 2) {
1632 Ice::Operand *Op =
1633 getRelativeOperand(NaClDecodeSignRotatedValue(Values[i]), BaseIndex);
1634 if (Op->getType() != Ty) {
1635 std::string Buffer;
1636 raw_string_ostream StrBuf(Buffer);
1637 StrBuf << "Phi node expects type " << Ty << " but found: " << Op;
Jim Stichnoth 2014/09/11 18:26:40 Nit: maybe "operand" or "instruction" instead of "
Karl 2014/09/11 21:43:04 Done.
1638 Error(StrBuf.str());
1639 return;
1640 }
1641 Phi->addArgument(Op, getBasicBlock(Values[i+1]));
Jim Stichnoth 2014/09/11 18:26:40 hmm, did clang-format really allow "i+1" without s
Karl 2014/09/11 21:43:04 Done.
1642 }
1643 CurrentNode->appendInst(Phi);
1644 break;
1645 }
1593 case naclbitc::FUNC_CODE_INST_ALLOCA: { 1646 case naclbitc::FUNC_CODE_INST_ALLOCA: {
1594 // ALLOCA: [Size, align] 1647 // ALLOCA: [Size, align]
1595 if (!isValidRecordSize(2, "function block alloca")) 1648 if (!isValidRecordSize(2, "function block alloca"))
1596 return; 1649 return;
1597 Ice::Operand *ByteCount = getRelativeOperand(Values[0]); 1650 Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex);
1598 if (ByteCount->getType() != Ice::IceType_i32) { 1651 if (ByteCount->getType() != Ice::IceType_i32) {
1599 std::string Buffer; 1652 std::string Buffer;
1600 raw_string_ostream StrBuf(Buffer); 1653 raw_string_ostream StrBuf(Buffer);
1601 StrBuf << "Alloca on non-i32 value. Found: " << ByteCount; 1654 StrBuf << "Alloca on non-i32 value. Found: " << ByteCount;
1602 Error(StrBuf.str()); 1655 Error(StrBuf.str());
1603 return; 1656 return;
1604 } 1657 }
1605 unsigned Alignment; 1658 unsigned Alignment;
1606 extractAlignment("Alloca", Values[1], Alignment); 1659 extractAlignment("Alloca", Values[1], Alignment);
1607 Ice::Variable *Dest = NextInstVar(Context->getIcePointerType()); 1660 CurrentNode->appendInst(
1608 Inst = Ice::InstAlloca::create(Func, ByteCount, Alignment, Dest); 1661 Ice::InstAlloca::create(Func, ByteCount, Alignment,
1662 getNextInstVar(Context->getIcePointerType())));
1609 break; 1663 break;
1610 } 1664 }
1611 case naclbitc::FUNC_CODE_INST_LOAD: { 1665 case naclbitc::FUNC_CODE_INST_LOAD: {
1612 // LOAD: [address, align, ty] 1666 // LOAD: [address, align, ty]
1613 if (!isValidRecordSize(3, "function block load")) 1667 if (!isValidRecordSize(3, "function block load"))
1614 return; 1668 return;
1615 Ice::Operand *Address = getRelativeOperand(Values[0]); 1669 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex);
1616 if (!isValidPointerType(Address, "Load")) 1670 if (!isValidPointerType(Address, "Load"))
1617 return; 1671 return;
1618 unsigned Alignment; 1672 unsigned Alignment;
1619 extractAlignment("Load", Values[1], Alignment); 1673 extractAlignment("Load", Values[1], Alignment);
1620 Ice::Type Ty = Context->convertToIceType(Context->getTypeByID(Values[2])); 1674 Ice::Type Ty = Context->convertToIceType(Context->getTypeByID(Values[2]));
1621 if (!isValidLoadStoreAlignment(Alignment, Ty, "Load")) 1675 if (!isValidLoadStoreAlignment(Alignment, Ty, "Load"))
1622 return; 1676 return;
1623 Ice::Variable *Dest = NextInstVar(Ty); 1677 CurrentNode->appendInst(
1624 Inst = Ice::InstLoad::create(Func, Dest, Address, Alignment); 1678 Ice::InstLoad::create(Func, getNextInstVar(Ty), Address, Alignment));
1625 break; 1679 break;
1626 } 1680 }
1627 case naclbitc::FUNC_CODE_INST_STORE: { 1681 case naclbitc::FUNC_CODE_INST_STORE: {
1628 // STORE: [address, value, align] 1682 // STORE: [address, value, align]
1629 if (!isValidRecordSize(3, "function block store")) 1683 if (!isValidRecordSize(3, "function block store"))
1630 return; 1684 return;
1631 Ice::Operand *Address = getRelativeOperand(Values[0]); 1685 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex);
1632 if (!isValidPointerType(Address, "Store")) 1686 if (!isValidPointerType(Address, "Store"))
1633 return; 1687 return;
1634 Ice::Operand *Value = getRelativeOperand(Values[1]); 1688 Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex);
1635 unsigned Alignment; 1689 unsigned Alignment;
1636 extractAlignment("Store", Values[2], Alignment); 1690 extractAlignment("Store", Values[2], Alignment);
1637 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store")) 1691 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store"))
1638 return; 1692 return;
1639 Inst = Ice::InstStore::create(Func, Value, Address, Alignment); 1693 CurrentNode->appendInst(
1694 Ice::InstStore::create(Func, Value, Address, Alignment));
1640 break; 1695 break;
1641 } 1696 }
1642 default: 1697 default:
1643 // Generate error message! 1698 // Generate error message!
1644 BlockParserBaseClass::ProcessRecord(); 1699 BlockParserBaseClass::ProcessRecord();
1645 break; 1700 break;
1646 } 1701 }
1647 if (Inst)
1648 CurrentNode->appendInst(Inst);
1649 } 1702 }
1650 1703
1651 /// Parses constants within a function block. 1704 /// Parses constants within a function block.
1652 class ConstantsParser : public BlockParserBaseClass { 1705 class ConstantsParser : public BlockParserBaseClass {
1653 ConstantsParser(const ConstantsParser &) LLVM_DELETED_FUNCTION; 1706 ConstantsParser(const ConstantsParser &) LLVM_DELETED_FUNCTION;
1654 ConstantsParser &operator=(const ConstantsParser &) LLVM_DELETED_FUNCTION; 1707 ConstantsParser &operator=(const ConstantsParser &) LLVM_DELETED_FUNCTION;
1655 1708
1656 public: 1709 public:
1657 ConstantsParser(unsigned BlockID, FunctionParser *FuncParser) 1710 ConstantsParser(unsigned BlockID, FunctionParser *FuncParser)
1658 : BlockParserBaseClass(BlockID, FuncParser), FuncParser(FuncParser), 1711 : BlockParserBaseClass(BlockID, FuncParser), FuncParser(FuncParser),
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
2031 if (TopLevelBlocks != 1) { 2084 if (TopLevelBlocks != 1) {
2032 errs() << IRFilename 2085 errs() << IRFilename
2033 << ": Contains more than one module. Found: " << TopLevelBlocks 2086 << ": Contains more than one module. Found: " << TopLevelBlocks
2034 << "\n"; 2087 << "\n";
2035 ErrorStatus = true; 2088 ErrorStatus = true;
2036 } 2089 }
2037 return; 2090 return;
2038 } 2091 }
2039 2092
2040 } // end of namespace Ice 2093 } // end of namespace Ice
OLDNEW
« no previous file with comments | « no previous file | tests_lit/reader_tests/phi.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698