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

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 issues raised in patch set 2. 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(Ice::InstArithmetic::create(
1364 Inst = Ice::InstArithmetic::create(Func, Opcode, Dest, Op1, Op2); 1371 Func, Opcode, getNextInstVar(Type1), Op1, Op2));
1365 break; 1372 break;
1366 } 1373 }
1367 case naclbitc::FUNC_CODE_INST_CAST: { 1374 case naclbitc::FUNC_CODE_INST_CAST: {
1368 // CAST: [opval, destty, castopc] 1375 // CAST: [opval, destty, castopc]
1369 if (!isValidRecordSize(3, "function block cast")) 1376 if (!isValidRecordSize(3, "function block cast"))
1370 return; 1377 return;
1371 Ice::Operand *Src = getRelativeOperand(Values[0]); 1378 Ice::Operand *Src = getRelativeOperand(Values[0], BaseIndex);
1372 Type *CastType = Context->getTypeByID(Values[1]); 1379 Type *CastType = Context->getTypeByID(Values[1]);
1373 Instruction::CastOps LLVMCastOp; 1380 Instruction::CastOps LLVMCastOp;
1374 Ice::InstCast::OpKind CastKind; 1381 Ice::InstCast::OpKind CastKind;
1375 if (!naclbitc::DecodeCastOpcode(Values[2], LLVMCastOp) || 1382 if (!naclbitc::DecodeCastOpcode(Values[2], LLVMCastOp) ||
1376 !convertLLVMCastOpToIceOp(LLVMCastOp, CastKind)) { 1383 !convertLLVMCastOpToIceOp(LLVMCastOp, CastKind)) {
1377 std::string Buffer; 1384 std::string Buffer;
1378 raw_string_ostream StrBuf(Buffer); 1385 raw_string_ostream StrBuf(Buffer);
1379 StrBuf << "Cast opcode not understood: " << Values[2]; 1386 StrBuf << "Cast opcode not understood: " << Values[2];
1380 Error(StrBuf.str()); 1387 Error(StrBuf.str());
1381 return; 1388 return;
1382 } 1389 }
1383 Type *SrcType = Context->convertToLLVMType(Src->getType()); 1390 Type *SrcType = Context->convertToLLVMType(Src->getType());
1384 if (!CastInst::castIsValid(LLVMCastOp, SrcType, CastType)) { 1391 if (!CastInst::castIsValid(LLVMCastOp, SrcType, CastType)) {
1385 std::string Buffer; 1392 std::string Buffer;
1386 raw_string_ostream StrBuf(Buffer); 1393 raw_string_ostream StrBuf(Buffer);
1387 StrBuf << "Illegal cast: " << Instruction::getOpcodeName(LLVMCastOp) 1394 StrBuf << "Illegal cast: " << Instruction::getOpcodeName(LLVMCastOp)
1388 << " " << *SrcType << " to " << *CastType; 1395 << " " << *SrcType << " to " << *CastType;
1389 Error(StrBuf.str()); 1396 Error(StrBuf.str());
1390 return; 1397 return;
1391 } 1398 }
1392 Ice::Variable *Dest = NextInstVar(Context->convertToIceType(CastType)); 1399 CurrentNode->appendInst(Ice::InstCast::create(
1393 Inst = Ice::InstCast::create(Func, CastKind, Dest, Src); 1400 Func, CastKind, getNextInstVar(Context->convertToIceType(CastType)),
1401 Src));
1394 break; 1402 break;
1395 } 1403 }
1396 case naclbitc::FUNC_CODE_INST_VSELECT: { 1404 case naclbitc::FUNC_CODE_INST_VSELECT: {
1397 // VSELECT: [opval, opval, pred] 1405 // VSELECT: [opval, opval, pred]
1398 Ice::Operand *ThenVal = getOperand(convertRelativeToAbsIndex(Values[0])); 1406 Ice::Operand *ThenVal = getRelativeOperand(Values[0], BaseIndex);
1399 Ice::Type ThenType = ThenVal->getType(); 1407 Ice::Type ThenType = ThenVal->getType();
1400 Ice::Operand *ElseVal = getOperand(convertRelativeToAbsIndex(Values[1])); 1408 Ice::Operand *ElseVal = getRelativeOperand(Values[1], BaseIndex);
1401 Ice::Type ElseType = ElseVal->getType(); 1409 Ice::Type ElseType = ElseVal->getType();
1402 if (ThenType != ElseType) { 1410 if (ThenType != ElseType) {
1403 std::string Buffer; 1411 std::string Buffer;
1404 raw_string_ostream StrBuf(Buffer); 1412 raw_string_ostream StrBuf(Buffer);
1405 StrBuf << "Select operands not same type. Found " << ThenType << " and " 1413 StrBuf << "Select operands not same type. Found " << ThenType << " and "
1406 << ElseType; 1414 << ElseType;
1407 Error(StrBuf.str()); 1415 Error(StrBuf.str());
1408 return; 1416 return;
1409 } 1417 }
1410 Ice::Operand *CondVal = getOperand(convertRelativeToAbsIndex(Values[2])); 1418 Ice::Operand *CondVal = getRelativeOperand(Values[2], BaseIndex);
1411 Ice::Type CondType = CondVal->getType(); 1419 Ice::Type CondType = CondVal->getType();
1412 if (isVectorType(CondType)) { 1420 if (isVectorType(CondType)) {
1413 if (!isVectorType(ThenType) || 1421 if (!isVectorType(ThenType) ||
1414 typeElementType(CondType) != Ice::IceType_i1 || 1422 typeElementType(CondType) != Ice::IceType_i1 ||
1415 typeNumElements(ThenType) != typeNumElements(CondType)) { 1423 typeNumElements(ThenType) != typeNumElements(CondType)) {
1416 std::string Buffer; 1424 std::string Buffer;
1417 raw_string_ostream StrBuf(Buffer); 1425 raw_string_ostream StrBuf(Buffer);
1418 StrBuf << "Select condition " << CondType 1426 StrBuf << "Select condition " << CondType
1419 << " not allowed for values of type " << ThenType; 1427 << " not allowed for values of type " << ThenType;
1420 Error(StrBuf.str()); 1428 Error(StrBuf.str());
1421 return; 1429 return;
1422 } 1430 }
1423 } else if (CondVal->getType() != Ice::IceType_i1) { 1431 } else if (CondVal->getType() != Ice::IceType_i1) {
1424 std::string Buffer; 1432 std::string Buffer;
1425 raw_string_ostream StrBuf(Buffer); 1433 raw_string_ostream StrBuf(Buffer);
1426 StrBuf << "Select condition not type i1. Found: " << CondVal->getType(); 1434 StrBuf << "Select condition not type i1. Found: " << CondVal->getType();
1427 Error(StrBuf.str()); 1435 Error(StrBuf.str());
1428 return; 1436 return;
1429 } 1437 }
1430 Ice::Variable *DestVal = NextInstVar(ThenType); 1438 CurrentNode->appendInst(Ice::InstSelect::create(
1431 Inst = Ice::InstSelect::create(Func, DestVal, CondVal, ThenVal, ElseVal); 1439 Func, getNextInstVar(ThenType), CondVal, ThenVal, ElseVal));
1432 break; 1440 break;
1433 } 1441 }
1434 case naclbitc::FUNC_CODE_INST_EXTRACTELT: { 1442 case naclbitc::FUNC_CODE_INST_EXTRACTELT: {
1435 // EXTRACTELT: [opval, opval] 1443 // EXTRACTELT: [opval, opval]
1436 if (!isValidRecordSize(2, "function block extract element")) 1444 if (!isValidRecordSize(2, "function block extract element"))
1437 return; 1445 return;
1438 Ice::Operand *Vec = getRelativeOperand(Values[0]); 1446 Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex);
1439 Ice::Type VecType = Vec->getType(); 1447 Ice::Type VecType = Vec->getType();
1440 if (!Ice::isVectorType(VecType)) { 1448 if (!Ice::isVectorType(VecType)) {
1441 std::string Buffer; 1449 std::string Buffer;
1442 raw_string_ostream StrBuf(Buffer); 1450 raw_string_ostream StrBuf(Buffer);
1443 StrBuf << "Extractelement not on vector. Found: " << Vec; 1451 StrBuf << "Extractelement not on vector. Found: " << Vec;
1444 Error(StrBuf.str()); 1452 Error(StrBuf.str());
1445 } 1453 }
1446 Ice::Operand *Index = getRelativeOperand(Values[1]); 1454 Ice::Operand *Index = getRelativeOperand(Values[1], BaseIndex);
1447 if (Index->getType() != Ice::IceType_i32) { 1455 if (Index->getType() != Ice::IceType_i32) {
1448 std::string Buffer; 1456 std::string Buffer;
1449 raw_string_ostream StrBuf(Buffer); 1457 raw_string_ostream StrBuf(Buffer);
1450 StrBuf << "Extractelement index not i32. Found: " << Index; 1458 StrBuf << "Extractelement index not i32. Found: " << Index;
1451 Error(StrBuf.str()); 1459 Error(StrBuf.str());
1452 } 1460 }
1453 // TODO(kschimpf): Restrict index to a legal constant index (once 1461 // TODO(kschimpf): Restrict index to a legal constant index (once
1454 // constants can be defined). 1462 // constants can be defined).
1455 Ice::Variable *Dest = NextInstVar(typeElementType(VecType)); 1463 CurrentNode->appendInst(Ice::InstExtractElement::create(
1456 Inst = Ice::InstExtractElement::create(Func, Dest, Vec, Index); 1464 Func, getNextInstVar(typeElementType(VecType)), Vec, Index));
1457 break; 1465 break;
1458 } 1466 }
1459 case naclbitc::FUNC_CODE_INST_INSERTELT: { 1467 case naclbitc::FUNC_CODE_INST_INSERTELT: {
1460 // INSERTELT: [opval, opval, opval] 1468 // INSERTELT: [opval, opval, opval]
1461 if (!isValidRecordSize(3, "function block insert element")) 1469 if (!isValidRecordSize(3, "function block insert element"))
1462 return; 1470 return;
1463 Ice::Operand *Vec = getRelativeOperand(Values[0]); 1471 Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex);
1464 Ice::Type VecType = Vec->getType(); 1472 Ice::Type VecType = Vec->getType();
1465 if (!Ice::isVectorType(VecType)) { 1473 if (!Ice::isVectorType(VecType)) {
1466 std::string Buffer; 1474 std::string Buffer;
1467 raw_string_ostream StrBuf(Buffer); 1475 raw_string_ostream StrBuf(Buffer);
1468 StrBuf << "Insertelement not on vector. Found: " << Vec; 1476 StrBuf << "Insertelement not on vector. Found: " << Vec;
1469 Error(StrBuf.str()); 1477 Error(StrBuf.str());
1470 } 1478 }
1471 Ice::Operand *Elt = getRelativeOperand(Values[1]); 1479 Ice::Operand *Elt = getRelativeOperand(Values[1], BaseIndex);
1472 Ice::Type EltType = Elt->getType(); 1480 Ice::Type EltType = Elt->getType();
1473 if (EltType != typeElementType(VecType)) { 1481 if (EltType != typeElementType(VecType)) {
1474 std::string Buffer; 1482 std::string Buffer;
1475 raw_string_ostream StrBuf(Buffer); 1483 raw_string_ostream StrBuf(Buffer);
1476 StrBuf << "Insertelement element not " << typeElementType(VecType) 1484 StrBuf << "Insertelement element not " << typeElementType(VecType)
1477 << ". Found: " << Elt; 1485 << ". Found: " << Elt;
1478 Error(StrBuf.str()); 1486 Error(StrBuf.str());
1479 } 1487 }
1480 Ice::Operand *Index = getRelativeOperand(Values[2]); 1488 Ice::Operand *Index = getRelativeOperand(Values[2], BaseIndex);
1481 if (Index->getType() != Ice::IceType_i32) { 1489 if (Index->getType() != Ice::IceType_i32) {
1482 std::string Buffer; 1490 std::string Buffer;
1483 raw_string_ostream StrBuf(Buffer); 1491 raw_string_ostream StrBuf(Buffer);
1484 StrBuf << "Insertelement index not i32. Found: " << Index; 1492 StrBuf << "Insertelement index not i32. Found: " << Index;
1485 Error(StrBuf.str()); 1493 Error(StrBuf.str());
1486 } 1494 }
1487 // TODO(kschimpf): Restrict index to a legal constant index (once 1495 // TODO(kschimpf): Restrict index to a legal constant index (once
1488 // constants can be defined). 1496 // constants can be defined).
1489 Ice::Variable *Dest = NextInstVar(EltType); 1497 CurrentNode->appendInst(Ice::InstInsertElement::create(
1490 Inst = Ice::InstInsertElement::create(Func, Dest, Vec, Elt, Index); 1498 Func, getNextInstVar(EltType), Vec, Elt, Index));
1491 break; 1499 break;
1492 } 1500 }
1493 case naclbitc::FUNC_CODE_INST_CMP2: { 1501 case naclbitc::FUNC_CODE_INST_CMP2: {
1494 // CMP2: [opval, opval, pred] 1502 // CMP2: [opval, opval, pred]
1495 if (!isValidRecordSize(3, "function block compare")) 1503 if (!isValidRecordSize(3, "function block compare"))
1496 return; 1504 return;
1497 Ice::Operand *Op1 = getRelativeOperand(Values[0]); 1505 Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex);
1498 Ice::Operand *Op2 = getRelativeOperand(Values[1]); 1506 Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex);
1499 Ice::Type Op1Type = Op1->getType(); 1507 Ice::Type Op1Type = Op1->getType();
1500 Ice::Type Op2Type = Op2->getType(); 1508 Ice::Type Op2Type = Op2->getType();
1501 if (Op1Type != Op2Type) { 1509 if (Op1Type != Op2Type) {
1502 std::string Buffer; 1510 std::string Buffer;
1503 raw_string_ostream StrBuf(Buffer); 1511 raw_string_ostream StrBuf(Buffer);
1504 StrBuf << "Compare argument types differ: " << Op1Type 1512 StrBuf << "Compare argument types differ: " << Op1Type
1505 << " and " << Op2Type; 1513 << " and " << Op2Type;
1506 Error(StrBuf.str()); 1514 Error(StrBuf.str());
1507 // TODO(kschimpf) Remove error recovery once implementation complete. 1515 // TODO(kschimpf) Remove error recovery once implementation complete.
1508 Op2 = Op1; 1516 Op2 = Op1;
1509 } 1517 }
1510 Ice::Type DestType = getCompareResultType(Op1Type); 1518 Ice::Type DestType = getCompareResultType(Op1Type);
1511 if (DestType == Ice::IceType_void) { 1519 if (DestType == Ice::IceType_void) {
1512 std::string Buffer; 1520 std::string Buffer;
1513 raw_string_ostream StrBuf(Buffer); 1521 raw_string_ostream StrBuf(Buffer);
1514 StrBuf << "Compare not defined for type " << Op1Type; 1522 StrBuf << "Compare not defined for type " << Op1Type;
1515 Error(StrBuf.str()); 1523 Error(StrBuf.str());
1516 return; 1524 return;
1517 } 1525 }
1518 Ice::Variable *Dest = NextInstVar(DestType); 1526 Ice::Variable *Dest = getNextInstVar(DestType);
1519 if (isIntegerType(Op1Type)) { 1527 if (isIntegerType(Op1Type)) {
1520 Ice::InstIcmp::ICond Cond; 1528 Ice::InstIcmp::ICond Cond;
1521 if (!convertNaClBitcICmpOpToIce(Values[2], Cond)) { 1529 if (!convertNaClBitcICmpOpToIce(Values[2], Cond)) {
1522 std::string Buffer; 1530 std::string Buffer;
1523 raw_string_ostream StrBuf(Buffer); 1531 raw_string_ostream StrBuf(Buffer);
1524 StrBuf << "Compare record contains unknown integer predicate index: " 1532 StrBuf << "Compare record contains unknown integer predicate index: "
1525 << Values[2]; 1533 << Values[2];
1526 Error(StrBuf.str()); 1534 Error(StrBuf.str());
1527 // TODO(kschimpf) Remove error recovery once implementation complete. 1535 // TODO(kschimpf) Remove error recovery once implementation complete.
1528 Cond = Ice::InstIcmp::Eq; 1536 Cond = Ice::InstIcmp::Eq;
1529 } 1537 }
1530 Inst = Ice::InstIcmp::create(Func, Cond, Dest, Op1, Op2); 1538 CurrentNode->appendInst(
1539 Ice::InstIcmp::create(Func, Cond, Dest, Op1, Op2));
1531 } else if (isFloatingType(Op1Type)){ 1540 } else if (isFloatingType(Op1Type)){
1532 Ice::InstFcmp::FCond Cond; 1541 Ice::InstFcmp::FCond Cond;
1533 if (!convertNaClBitcFCompOpToIce(Values[2], Cond)) { 1542 if (!convertNaClBitcFCompOpToIce(Values[2], Cond)) {
1534 std::string Buffer; 1543 std::string Buffer;
1535 raw_string_ostream StrBuf(Buffer); 1544 raw_string_ostream StrBuf(Buffer);
1536 StrBuf << "Compare record contains unknown float predicate index: " 1545 StrBuf << "Compare record contains unknown float predicate index: "
1537 << Values[2]; 1546 << Values[2];
1538 Error(StrBuf.str()); 1547 Error(StrBuf.str());
1539 // TODO(kschimpf) Remove error recovery once implementation complete. 1548 // TODO(kschimpf) Remove error recovery once implementation complete.
1540 Cond = Ice::InstFcmp::False; 1549 Cond = Ice::InstFcmp::False;
1541 } 1550 }
1542 Inst = Ice::InstFcmp::create(Func, Cond, Dest, Op1, Op2); 1551 CurrentNode->appendInst(
1552 Ice::InstFcmp::create(Func, Cond, Dest, Op1, Op2));
1543 } else { 1553 } else {
1544 // Not sure this can happen, but be safe. 1554 // Not sure this can happen, but be safe.
1545 std::string Buffer; 1555 std::string Buffer;
1546 raw_string_ostream StrBuf(Buffer); 1556 raw_string_ostream StrBuf(Buffer);
1547 StrBuf << "Compare on type not understood: " << Op1Type; 1557 StrBuf << "Compare on type not understood: " << Op1Type;
1548 Error(StrBuf.str()); 1558 Error(StrBuf.str());
1549 return; 1559 return;
1550 } 1560 }
1551 break; 1561 break;
1552 } 1562 }
1553 case naclbitc::FUNC_CODE_INST_RET: { 1563 case naclbitc::FUNC_CODE_INST_RET: {
1554 // RET: [opval?] 1564 // RET: [opval?]
1555 if (!isValidRecordSizeInRange(0, 1, "function block ret")) 1565 if (!isValidRecordSizeInRange(0, 1, "function block ret"))
1556 return; 1566 return;
1557 if (Values.size() == 0) { 1567 if (Values.size() == 0) {
1558 Inst = Ice::InstRet::create(Func); 1568 CurrentNode->appendInst(Ice::InstRet::create(Func));
1559 } else { 1569 } else {
1560 Inst = Ice::InstRet::create(Func, getRelativeOperand(Values[0])); 1570 CurrentNode->appendInst(
1571 Ice::InstRet::create(Func, getRelativeOperand(Values[0], BaseIndex)));
1561 } 1572 }
1562 InstIsTerminating = true; 1573 InstIsTerminating = true;
1563 break; 1574 break;
1564 } 1575 }
1565 case naclbitc::FUNC_CODE_INST_BR: { 1576 case naclbitc::FUNC_CODE_INST_BR: {
1566 if (Values.size() == 1) { 1577 if (Values.size() == 1) {
1567 // BR: [bb#] 1578 // BR: [bb#]
1568 Ice::CfgNode *Block = getBranchBasicBlock(Values[0]); 1579 Ice::CfgNode *Block = getBranchBasicBlock(Values[0]);
1569 if (Block == NULL) 1580 if (Block == NULL)
1570 return; 1581 return;
1571 Inst = Ice::InstBr::create(Func, Block); 1582 CurrentNode->appendInst(Ice::InstBr::create(Func, Block));
1572 } else { 1583 } else {
1573 // BR: [bb#, bb#, opval] 1584 // BR: [bb#, bb#, opval]
1574 if (!isValidRecordSize(3, "function block branch")) 1585 if (!isValidRecordSize(3, "function block branch"))
1575 return; 1586 return;
1576 Ice::Operand *Cond = getRelativeOperand(Values[2]); 1587 Ice::Operand *Cond = getRelativeOperand(Values[2], BaseIndex);
1577 if (Cond->getType() != Ice::IceType_i1) { 1588 if (Cond->getType() != Ice::IceType_i1) {
1578 std::string Buffer; 1589 std::string Buffer;
1579 raw_string_ostream StrBuf(Buffer); 1590 raw_string_ostream StrBuf(Buffer);
1580 StrBuf << "Branch condition not i1"; 1591 StrBuf << "Branch condition not i1";
1581 Error(StrBuf.str()); 1592 Error(StrBuf.str());
1582 return; 1593 return;
1583 } 1594 }
1584 Ice::CfgNode *ThenBlock = getBranchBasicBlock(Values[0]); 1595 Ice::CfgNode *ThenBlock = getBranchBasicBlock(Values[0]);
1585 Ice::CfgNode *ElseBlock = getBranchBasicBlock(Values[1]); 1596 Ice::CfgNode *ElseBlock = getBranchBasicBlock(Values[1]);
1586 if (ThenBlock == NULL || ElseBlock == NULL) 1597 if (ThenBlock == NULL || ElseBlock == NULL)
1587 return; 1598 return;
1588 Inst = Ice::InstBr::create(Func, Cond, ThenBlock, ElseBlock); 1599 CurrentNode->appendInst(
1600 Ice::InstBr::create(Func, Cond, ThenBlock, ElseBlock));
1589 } 1601 }
1590 InstIsTerminating = true; 1602 InstIsTerminating = true;
1591 break; 1603 break;
1592 } 1604 }
1605 case naclbitc::FUNC_CODE_INST_PHI: {
1606 // PHI: [ty, val1, bb1, ..., valN, bbN] for n >= 2.
1607 if (!isValidRecordSizeAtLeast(3, "function block phi"))
1608 return;
1609 if ((Values.size() & 0x1) == 0) {
1610 // Not an odd number of values.
1611 std::string Buffer;
1612 raw_string_ostream StrBuf(Buffer);
1613 StrBuf << "function block phi record size not valid: " << Values.size();
1614 Error(StrBuf.str());
1615 return;
1616 }
1617 Ice::Type Ty = Context->convertToIceType(Context->getTypeByID(Values[0]));
1618 if (Ty == Ice::IceType_void) {
1619 Error("Phi record using type void not allowed");
1620 return;
1621 }
1622 Ice::Variable *Dest = getNextInstVar(Ty);
1623 Ice::InstPhi *Phi = Ice::InstPhi::create(Func, Values.size() >> 1, Dest);
1624 for (unsigned i = 1; i < Values.size(); i += 2) {
1625 Ice::Operand *Op =
1626 getRelativeOperand(NaClDecodeSignRotatedValue(Values[i]), BaseIndex);
1627 if (Op->getType() != Ty) {
1628 std::string Buffer;
1629 raw_string_ostream StrBuf(Buffer);
1630 StrBuf << "Phi instruction expects type " << Ty << " but found: " << Op;
1631 Error(StrBuf.str());
1632 return;
1633 }
1634 Phi->addArgument(Op, getBasicBlock(Values[i + 1]));
1635 }
1636 CurrentNode->appendInst(Phi);
1637 break;
1638 }
1593 case naclbitc::FUNC_CODE_INST_ALLOCA: { 1639 case naclbitc::FUNC_CODE_INST_ALLOCA: {
1594 // ALLOCA: [Size, align] 1640 // ALLOCA: [Size, align]
1595 if (!isValidRecordSize(2, "function block alloca")) 1641 if (!isValidRecordSize(2, "function block alloca"))
1596 return; 1642 return;
1597 Ice::Operand *ByteCount = getRelativeOperand(Values[0]); 1643 Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex);
1598 if (ByteCount->getType() != Ice::IceType_i32) { 1644 if (ByteCount->getType() != Ice::IceType_i32) {
1599 std::string Buffer; 1645 std::string Buffer;
1600 raw_string_ostream StrBuf(Buffer); 1646 raw_string_ostream StrBuf(Buffer);
1601 StrBuf << "Alloca on non-i32 value. Found: " << ByteCount; 1647 StrBuf << "Alloca on non-i32 value. Found: " << ByteCount;
1602 Error(StrBuf.str()); 1648 Error(StrBuf.str());
1603 return; 1649 return;
1604 } 1650 }
1605 unsigned Alignment; 1651 unsigned Alignment;
1606 extractAlignment("Alloca", Values[1], Alignment); 1652 extractAlignment("Alloca", Values[1], Alignment);
1607 Ice::Variable *Dest = NextInstVar(Context->getIcePointerType()); 1653 CurrentNode->appendInst(
1608 Inst = Ice::InstAlloca::create(Func, ByteCount, Alignment, Dest); 1654 Ice::InstAlloca::create(Func, ByteCount, Alignment,
1655 getNextInstVar(Context->getIcePointerType())));
1609 break; 1656 break;
1610 } 1657 }
1611 case naclbitc::FUNC_CODE_INST_LOAD: { 1658 case naclbitc::FUNC_CODE_INST_LOAD: {
1612 // LOAD: [address, align, ty] 1659 // LOAD: [address, align, ty]
1613 if (!isValidRecordSize(3, "function block load")) 1660 if (!isValidRecordSize(3, "function block load"))
1614 return; 1661 return;
1615 Ice::Operand *Address = getRelativeOperand(Values[0]); 1662 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex);
1616 if (!isValidPointerType(Address, "Load")) 1663 if (!isValidPointerType(Address, "Load"))
1617 return; 1664 return;
1618 unsigned Alignment; 1665 unsigned Alignment;
1619 extractAlignment("Load", Values[1], Alignment); 1666 extractAlignment("Load", Values[1], Alignment);
1620 Ice::Type Ty = Context->convertToIceType(Context->getTypeByID(Values[2])); 1667 Ice::Type Ty = Context->convertToIceType(Context->getTypeByID(Values[2]));
1621 if (!isValidLoadStoreAlignment(Alignment, Ty, "Load")) 1668 if (!isValidLoadStoreAlignment(Alignment, Ty, "Load"))
1622 return; 1669 return;
1623 Ice::Variable *Dest = NextInstVar(Ty); 1670 CurrentNode->appendInst(
1624 Inst = Ice::InstLoad::create(Func, Dest, Address, Alignment); 1671 Ice::InstLoad::create(Func, getNextInstVar(Ty), Address, Alignment));
1625 break; 1672 break;
1626 } 1673 }
1627 case naclbitc::FUNC_CODE_INST_STORE: { 1674 case naclbitc::FUNC_CODE_INST_STORE: {
1628 // STORE: [address, value, align] 1675 // STORE: [address, value, align]
1629 if (!isValidRecordSize(3, "function block store")) 1676 if (!isValidRecordSize(3, "function block store"))
1630 return; 1677 return;
1631 Ice::Operand *Address = getRelativeOperand(Values[0]); 1678 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex);
1632 if (!isValidPointerType(Address, "Store")) 1679 if (!isValidPointerType(Address, "Store"))
1633 return; 1680 return;
1634 Ice::Operand *Value = getRelativeOperand(Values[1]); 1681 Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex);
1635 unsigned Alignment; 1682 unsigned Alignment;
1636 extractAlignment("Store", Values[2], Alignment); 1683 extractAlignment("Store", Values[2], Alignment);
1637 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store")) 1684 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store"))
1638 return; 1685 return;
1639 Inst = Ice::InstStore::create(Func, Value, Address, Alignment); 1686 CurrentNode->appendInst(
1687 Ice::InstStore::create(Func, Value, Address, Alignment));
1640 break; 1688 break;
1641 } 1689 }
1642 default: 1690 default:
1643 // Generate error message! 1691 // Generate error message!
1644 BlockParserBaseClass::ProcessRecord(); 1692 BlockParserBaseClass::ProcessRecord();
1645 break; 1693 break;
1646 } 1694 }
1647 if (Inst)
1648 CurrentNode->appendInst(Inst);
1649 } 1695 }
1650 1696
1651 /// Parses constants within a function block. 1697 /// Parses constants within a function block.
1652 class ConstantsParser : public BlockParserBaseClass { 1698 class ConstantsParser : public BlockParserBaseClass {
1653 ConstantsParser(const ConstantsParser &) LLVM_DELETED_FUNCTION; 1699 ConstantsParser(const ConstantsParser &) LLVM_DELETED_FUNCTION;
1654 ConstantsParser &operator=(const ConstantsParser &) LLVM_DELETED_FUNCTION; 1700 ConstantsParser &operator=(const ConstantsParser &) LLVM_DELETED_FUNCTION;
1655 1701
1656 public: 1702 public:
1657 ConstantsParser(unsigned BlockID, FunctionParser *FuncParser) 1703 ConstantsParser(unsigned BlockID, FunctionParser *FuncParser)
1658 : BlockParserBaseClass(BlockID, FuncParser), FuncParser(FuncParser), 1704 : BlockParserBaseClass(BlockID, FuncParser), FuncParser(FuncParser),
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
2031 if (TopLevelBlocks != 1) { 2077 if (TopLevelBlocks != 1) {
2032 errs() << IRFilename 2078 errs() << IRFilename
2033 << ": Contains more than one module. Found: " << TopLevelBlocks 2079 << ": Contains more than one module. Found: " << TopLevelBlocks
2034 << "\n"; 2080 << "\n";
2035 ErrorStatus = true; 2081 ErrorStatus = true;
2036 } 2082 }
2037 return; 2083 return;
2038 } 2084 }
2039 2085
2040 } // end of namespace Ice 2086 } // 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