OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |