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 1005 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1016 Op = Ice::InstArithmetic::And; | 1016 Op = Ice::InstArithmetic::And; |
1017 return isValidIntegerLogicalOp(Op, Ty); | 1017 return isValidIntegerLogicalOp(Op, Ty); |
1018 case Instruction::Or: | 1018 case Instruction::Or: |
1019 Op = Ice::InstArithmetic::Or; | 1019 Op = Ice::InstArithmetic::Or; |
1020 return isValidIntegerLogicalOp(Op, Ty); | 1020 return isValidIntegerLogicalOp(Op, Ty); |
1021 case Instruction::Xor: | 1021 case Instruction::Xor: |
1022 Op = Ice::InstArithmetic::Xor; | 1022 Op = Ice::InstArithmetic::Xor; |
1023 return isValidIntegerLogicalOp(Op, Ty); | 1023 return isValidIntegerLogicalOp(Op, Ty); |
1024 } | 1024 } |
1025 } | 1025 } |
1026 | |
1027 /// Converts an LLVM cast opcode LLVMCastOp to the corresponding Ice | |
1028 /// cast opcode and assigns to CastKind. Returns true if successful, | |
1029 /// false otherwise. | |
1030 bool convertLLVMCastOpToIceOp(Instruction::CastOps LLVMCastOp, | |
1031 Ice::InstCast::OpKind &CastKind) { | |
1032 switch (LLVMCastOp) { | |
1033 case Instruction::ZExt: | |
1034 CastKind = Ice::InstCast::Zext; | |
1035 break; | |
1036 case Instruction::SExt: | |
1037 CastKind = Ice::InstCast::Sext; | |
1038 break; | |
1039 case Instruction::Trunc: | |
1040 CastKind = Ice::InstCast::Trunc; | |
1041 break; | |
1042 case Instruction::FPTrunc: | |
1043 CastKind = Ice::InstCast::Fptrunc; | |
1044 break; | |
1045 case Instruction::FPExt: | |
1046 CastKind = Ice::InstCast::Fpext; | |
1047 break; | |
1048 case Instruction::FPToSI: | |
1049 CastKind = Ice::InstCast::Fptosi; | |
1050 break; | |
1051 case Instruction::FPToUI: | |
1052 CastKind = Ice::InstCast::Fptoui; | |
1053 break; | |
1054 case Instruction::SIToFP: | |
1055 CastKind = Ice::InstCast::Sitofp; | |
1056 break; | |
1057 case Instruction::UIToFP: | |
1058 CastKind = Ice::InstCast::Uitofp; | |
1059 break; | |
1060 case Instruction::BitCast: | |
1061 CastKind = Ice::InstCast::Bitcast; | |
1062 break; | |
1063 default: | |
1064 return false; | |
1065 } | |
1066 return true; | |
1067 } | |
1026 }; | 1068 }; |
1027 | 1069 |
1028 FunctionParser::~FunctionParser() { | 1070 FunctionParser::~FunctionParser() { |
1029 if (getTranslator().getFlags().SubzeroTimingEnabled) { | 1071 if (getTranslator().getFlags().SubzeroTimingEnabled) { |
1030 errs() << "[Subzero timing] Convert function " << Func->getFunctionName() | 1072 errs() << "[Subzero timing] Convert function " << Func->getFunctionName() |
1031 << ": " << TConvert.getElapsedSec() << " sec\n"; | 1073 << ": " << TConvert.getElapsedSec() << " sec\n"; |
1032 } | 1074 } |
1033 } | 1075 } |
1034 | 1076 |
1035 void FunctionParser::ReportInvalidBinopOpcode(unsigned Opcode, Ice::Type Ty) { | 1077 void FunctionParser::ReportInvalidBinopOpcode(unsigned Opcode, Ice::Type Ty) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1073 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); | 1115 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
1074 if (InstIsTerminating) { | 1116 if (InstIsTerminating) { |
1075 InstIsTerminating = false; | 1117 InstIsTerminating = false; |
1076 CurrentNode = GetBasicBlock(++CurrentBbIndex); | 1118 CurrentNode = GetBasicBlock(++CurrentBbIndex); |
1077 } | 1119 } |
1078 Ice::Inst *Inst = NULL; | 1120 Ice::Inst *Inst = NULL; |
1079 switch (Record.GetCode()) { | 1121 switch (Record.GetCode()) { |
1080 case naclbitc::FUNC_CODE_DECLAREBLOCKS: { | 1122 case naclbitc::FUNC_CODE_DECLAREBLOCKS: { |
1081 // DECLAREBLOCKS: [n] | 1123 // DECLAREBLOCKS: [n] |
1082 if (!isValidRecordSize(1, "function block count")) | 1124 if (!isValidRecordSize(1, "function block count")) |
1083 break; | 1125 return; |
1084 if (Func->getNodes().size() != 1) { | 1126 if (Func->getNodes().size() != 1) { |
1085 Error("Duplicate function block count record"); | 1127 Error("Duplicate function block count record"); |
1086 return; | 1128 return; |
1087 } | 1129 } |
1088 uint32_t NumBbs = Values[0]; | 1130 uint32_t NumBbs = Values[0]; |
1089 if (NumBbs == 0) { | 1131 if (NumBbs == 0) { |
1090 Error("Functions must contain at least one basic block."); | 1132 Error("Functions must contain at least one basic block."); |
1091 // TODO(kschimpf) Remove error recovery once implementation complete. | 1133 // TODO(kschimpf) Remove error recovery once implementation complete. |
1092 NumBbs = 1; | 1134 NumBbs = 1; |
1093 } | 1135 } |
1094 // Install the basic blocks, skipping bb0 which was created in the | 1136 // Install the basic blocks, skipping bb0 which was created in the |
1095 // constructor. | 1137 // constructor. |
1096 for (size_t i = 1; i < NumBbs; ++i) | 1138 for (size_t i = 1; i < NumBbs; ++i) |
1097 InstallNextBasicBlock(); | 1139 InstallNextBasicBlock(); |
1098 break; | 1140 break; |
1099 } | 1141 } |
1100 case naclbitc::FUNC_CODE_INST_BINOP: { | 1142 case naclbitc::FUNC_CODE_INST_BINOP: { |
1101 // BINOP: [opval, opval, opcode] | 1143 // BINOP: [opval, opval, opcode] |
1102 if (!isValidRecordSize(3, "function block binop")) | 1144 if (!isValidRecordSize(3, "function block binop")) |
1103 break; | 1145 return; |
1104 Ice::Operand *Op1 = getOperand(convertRelativeToAbsIndex(Values[0])); | 1146 Ice::Operand *Op1 = getOperand(convertRelativeToAbsIndex(Values[0])); |
1105 Ice::Operand *Op2 = getOperand(convertRelativeToAbsIndex(Values[1])); | 1147 Ice::Operand *Op2 = getOperand(convertRelativeToAbsIndex(Values[1])); |
1106 Ice::Type Type1 = Op1->getType(); | 1148 Ice::Type Type1 = Op1->getType(); |
1107 Ice::Type Type2 = Op2->getType(); | 1149 Ice::Type Type2 = Op2->getType(); |
1108 if (Type1 != Type2) { | 1150 if (Type1 != Type2) { |
1109 std::string Buffer; | 1151 std::string Buffer; |
1110 raw_string_ostream StrBuf(Buffer); | 1152 raw_string_ostream StrBuf(Buffer); |
1111 StrBuf << "Binop argument types differ: " << Type1 << " and " << Type2; | 1153 StrBuf << "Binop argument types differ: " << Type1 << " and " << Type2; |
1112 Error(StrBuf.str()); | 1154 Error(StrBuf.str()); |
1113 // TODO(kschimpf) Remove error recovery once implementation complete. | 1155 // TODO(kschimpf) Remove error recovery once implementation complete. |
1114 Op2 = Op1; | 1156 Op2 = Op1; |
1115 } | 1157 } |
1116 | 1158 |
1117 Ice::InstArithmetic::OpKind Opcode; | 1159 Ice::InstArithmetic::OpKind Opcode; |
1118 if (!convertBinopOpcode(Values[2], Type1, Opcode)) | 1160 if (!convertBinopOpcode(Values[2], Type1, Opcode)) |
1119 break; | 1161 return; |
1120 Ice::Variable *Dest = NextInstVar(Type1); | 1162 Ice::Variable *Dest = NextInstVar(Type1); |
1121 Inst = Ice::InstArithmetic::create(Func, Opcode, Dest, Op1, Op2); | 1163 Inst = Ice::InstArithmetic::create(Func, Opcode, Dest, Op1, Op2); |
1122 break; | 1164 break; |
1123 } | 1165 } |
1166 case naclbitc::FUNC_CODE_INST_CAST: { | |
1167 // CAST: [opval, destty, castopc] | |
1168 if (!isValidRecordSize(3, "function block cast")) | |
1169 return; | |
1170 Ice::Operand *Src = getOperand(convertRelativeToAbsIndex(Values[0])); | |
1171 Type *CastType = Context->getTypeByID(Values[1]); | |
1172 Instruction::CastOps LLVMCastOp; | |
1173 Ice::InstCast::OpKind CastKind; | |
1174 if (!naclbitc::DecodeCastOpcode(Values[2], LLVMCastOp) | |
jvoung (off chromium)
2014/08/28 21:35:03
Should we just make one switch statement that fold
Karl
2014/08/29 16:00:29
Done.
| |
1175 || !convertLLVMCastOpToIceOp(LLVMCastOp, CastKind)) { | |
1176 std::string Buffer; | |
1177 raw_string_ostream StrBuf(Buffer); | |
1178 StrBuf << "Cast opcode not understood: " << Values[2]; | |
1179 Error(StrBuf.str()); | |
1180 return; | |
1181 } | |
1182 Type *SrcType = Context->convertToLLVMType(Src->getType()); | |
1183 if (!CastInst::castIsValid(LLVMCastOp, SrcType, CastType)) { | |
1184 std::string Buffer; | |
1185 raw_string_ostream StrBuf(Buffer); | |
1186 StrBuf << "Illegal cast: " << Instruction::getOpcodeName(LLVMCastOp) | |
1187 << " " << *SrcType << " to " << *CastType; | |
1188 Error(StrBuf.str()); | |
1189 return; | |
1190 } | |
1191 Ice::Variable *Dest = NextInstVar(Context->convertToIceType(CastType)); | |
1192 Inst = Ice::InstCast::create(Func, CastKind, Dest, Src); | |
1193 break; | |
1194 } | |
1124 case naclbitc::FUNC_CODE_INST_RET: { | 1195 case naclbitc::FUNC_CODE_INST_RET: { |
1125 // RET: [opval?] | 1196 // RET: [opval?] |
1126 InstIsTerminating = true; | 1197 InstIsTerminating = true; |
1127 if (!isValidRecordSizeInRange(0, 1, "function block ret")) | 1198 if (!isValidRecordSizeInRange(0, 1, "function block ret")) |
1128 break; | 1199 break; |
jvoung (off chromium)
2014/08/28 21:35:03
Should this be a return too?
Karl
2014/08/29 16:00:29
Good point.
| |
1129 if (Values.size() == 0) { | 1200 if (Values.size() == 0) { |
1130 Inst = Ice::InstRet::create(Func); | 1201 Inst = Ice::InstRet::create(Func); |
1131 } else { | 1202 } else { |
1132 Inst = Ice::InstRet::create( | 1203 Inst = Ice::InstRet::create( |
1133 Func, getOperand(convertRelativeToAbsIndex(Values[0]))); | 1204 Func, getOperand(convertRelativeToAbsIndex(Values[0]))); |
1134 } | 1205 } |
1135 break; | 1206 break; |
1136 } | 1207 } |
1137 default: | 1208 default: |
1138 // Generate error message! | 1209 // Generate error message! |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1301 if (TopLevelBlocks != 1) { | 1372 if (TopLevelBlocks != 1) { |
1302 errs() << IRFilename | 1373 errs() << IRFilename |
1303 << ": Contains more than one module. Found: " << TopLevelBlocks | 1374 << ": Contains more than one module. Found: " << TopLevelBlocks |
1304 << "\n"; | 1375 << "\n"; |
1305 ErrorStatus = true; | 1376 ErrorStatus = true; |
1306 } | 1377 } |
1307 return; | 1378 return; |
1308 } | 1379 } |
1309 | 1380 |
1310 } // end of namespace Ice | 1381 } // end of namespace Ice |
OLD | NEW |