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 /// \file | 10 /// \file |
(...skipping 2626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2637 return; | 2637 return; |
2638 } else { | 2638 } else { |
2639 if (!isValidRecordSizeAtLeast(3, "call indirect")) | 2639 if (!isValidRecordSizeAtLeast(3, "call indirect")) |
2640 return; | 2640 return; |
2641 ParamsStartIndex = 3; | 2641 ParamsStartIndex = 3; |
2642 } | 2642 } |
2643 | 2643 |
2644 // Extract out the called function and its return type. | 2644 // Extract out the called function and its return type. |
2645 uint32_t CalleeIndex = convertRelativeToAbsIndex(Values[1], BaseIndex); | 2645 uint32_t CalleeIndex = convertRelativeToAbsIndex(Values[1], BaseIndex); |
2646 Ice::Operand *Callee = getOperand(CalleeIndex); | 2646 Ice::Operand *Callee = getOperand(CalleeIndex); |
| 2647 const Ice::FuncSigType *Signature = nullptr; |
2647 Ice::Type ReturnType = Ice::IceType_void; | 2648 Ice::Type ReturnType = Ice::IceType_void; |
2648 const Ice::Intrinsics::FullIntrinsicInfo *IntrinsicInfo = nullptr; | 2649 const Ice::Intrinsics::FullIntrinsicInfo *IntrinsicInfo = nullptr; |
2649 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) { | 2650 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) { |
2650 Ice::FunctionDeclaration *Fcn = Context->getFunctionByID(CalleeIndex); | 2651 Ice::FunctionDeclaration *Fcn = Context->getFunctionByID(CalleeIndex); |
2651 const Ice::FuncSigType &Signature = Fcn->getSignature(); | 2652 Signature = &Fcn->getSignature(); |
2652 ReturnType = Signature.getReturnType(); | 2653 ReturnType = Signature->getReturnType(); |
2653 | 2654 |
2654 // Check if this direct call is to an Intrinsic (starts with "llvm.") | 2655 // Check if this direct call is to an Intrinsic (starts with "llvm.") |
2655 bool BadIntrinsic; | 2656 bool BadIntrinsic; |
2656 const Ice::IceString &Name = Fcn->getName(); | 2657 const Ice::IceString &Name = Fcn->getName(); |
2657 IntrinsicInfo = getTranslator().getContext()->getIntrinsicsInfo().find( | 2658 IntrinsicInfo = getTranslator().getContext()->getIntrinsicsInfo().find( |
2658 Name, BadIntrinsic); | 2659 Name, BadIntrinsic); |
2659 if (BadIntrinsic) { | 2660 if (BadIntrinsic) { |
2660 std::string Buffer; | 2661 std::string Buffer; |
2661 raw_string_ostream StrBuf(Buffer); | 2662 raw_string_ostream StrBuf(Buffer); |
2662 StrBuf << "Invalid PNaCl intrinsic call to " << Name; | 2663 StrBuf << "Invalid PNaCl intrinsic call to " << Name; |
2663 Error(StrBuf.str()); | 2664 Error(StrBuf.str()); |
2664 appendErrorInstruction(ReturnType); | 2665 if (ReturnType != Ice::IceType_void) |
| 2666 appendErrorInstruction(ReturnType); |
2665 return; | 2667 return; |
2666 } | 2668 } |
2667 } else { | 2669 } else { |
2668 ReturnType = Context->getSimpleTypeByID(Values[2]); | 2670 ReturnType = Context->getSimpleTypeByID(Values[2]); |
2669 } | 2671 } |
2670 | 2672 |
| 2673 // Check return type. |
| 2674 if (IntrinsicInfo == nullptr && !isCallReturnType(ReturnType)) { |
| 2675 std::string Buffer; |
| 2676 raw_string_ostream StrBuf(Buffer); |
| 2677 StrBuf << "Return type of called function is invalid: " << ReturnType; |
| 2678 Error(StrBuf.str()); |
| 2679 ReturnType = Ice::IceType_i32; |
| 2680 } |
| 2681 |
2671 // Extract call information. | 2682 // Extract call information. |
2672 uint64_t CCInfo = Values[0]; | 2683 uint64_t CCInfo = Values[0]; |
2673 CallingConv::ID CallingConv; | 2684 CallingConv::ID CallingConv; |
2674 if (!naclbitc::DecodeCallingConv(CCInfo >> 1, CallingConv)) { | 2685 if (!naclbitc::DecodeCallingConv(CCInfo >> 1, CallingConv)) { |
2675 std::string Buffer; | 2686 std::string Buffer; |
2676 raw_string_ostream StrBuf(Buffer); | 2687 raw_string_ostream StrBuf(Buffer); |
2677 StrBuf << "Function call calling convention value " << (CCInfo >> 1) | 2688 StrBuf << "Function call calling convention value " << (CCInfo >> 1) |
2678 << " not understood."; | 2689 << " not understood."; |
2679 Error(StrBuf.str()); | 2690 Error(StrBuf.str()); |
2680 appendErrorInstruction(ReturnType); | 2691 if (ReturnType != Ice::IceType_void) |
| 2692 appendErrorInstruction(ReturnType); |
2681 return; | 2693 return; |
2682 } | 2694 } |
2683 bool IsTailCall = static_cast<bool>(CCInfo & 1); | 2695 bool IsTailCall = static_cast<bool>(CCInfo & 1); |
2684 Ice::SizeT NumParams = Values.size() - ParamsStartIndex; | 2696 Ice::SizeT NumParams = Values.size() - ParamsStartIndex; |
2685 | 2697 if (Signature && NumParams != Signature->getNumArgs()) { |
| 2698 std::string Buffer; |
| 2699 raw_string_ostream StrBuf(Buffer); |
| 2700 StrBuf << "Call has " << NumParams |
| 2701 << " parameters. Signature expects: " << Signature->getNumArgs(); |
| 2702 Error(StrBuf.str()); |
| 2703 // Error recover by only checking parameters in both signature and call. |
| 2704 NumParams = std::min(NumParams, Signature->getNumArgs()); |
| 2705 } |
2686 if (isIRGenerationDisabled()) { | 2706 if (isIRGenerationDisabled()) { |
2687 assert(Callee == nullptr); | 2707 assert(Callee == nullptr); |
2688 // Check that parameters are defined. | 2708 // Check that parameters are defined. |
2689 for (Ice::SizeT ParamIndex = 0; ParamIndex < NumParams; ++ParamIndex) { | 2709 for (Ice::SizeT ParamIndex = 0; ParamIndex < NumParams; ++ParamIndex) { |
2690 assert(getRelativeOperand(Values[ParamsStartIndex + ParamIndex], | 2710 assert(getRelativeOperand(Values[ParamsStartIndex + ParamIndex], |
2691 BaseIndex) == nullptr); | 2711 BaseIndex) == nullptr); |
2692 } | 2712 } |
2693 // Define value slot only if value returned. | 2713 // Define value slot only if value returned. |
2694 if (ReturnType != Ice::IceType_void) | 2714 if (ReturnType != Ice::IceType_void) |
2695 setNextLocalInstIndex(nullptr); | 2715 setNextLocalInstIndex(nullptr); |
2696 return; | 2716 return; |
2697 } | 2717 } |
2698 | |
2699 // Create the call instruction. | 2718 // Create the call instruction. |
2700 Ice::Variable *Dest = (ReturnType == Ice::IceType_void) | 2719 Ice::Variable *Dest = (ReturnType == Ice::IceType_void) |
2701 ? nullptr | 2720 ? nullptr |
2702 : getNextInstVar(ReturnType); | 2721 : getNextInstVar(ReturnType); |
2703 Ice::InstCall *Inst = nullptr; | 2722 std::unique_ptr<Ice::InstCall> Inst; |
2704 if (IntrinsicInfo) { | 2723 if (IntrinsicInfo) { |
2705 Inst = Ice::InstIntrinsicCall::create(Func.get(), NumParams, Dest, Callee, | 2724 Inst.reset(Ice::InstIntrinsicCall::create(Func.get(), NumParams, Dest, |
2706 IntrinsicInfo->Info); | 2725 Callee, IntrinsicInfo->Info)); |
2707 } else { | 2726 } else { |
2708 Inst = Ice::InstCall::create(Func.get(), NumParams, Dest, Callee, | 2727 Inst.reset(Ice::InstCall::create(Func.get(), NumParams, Dest, Callee, |
2709 IsTailCall); | 2728 IsTailCall)); |
2710 } | 2729 } |
2711 | 2730 |
2712 // Add parameters. | 2731 // Add parameters. |
2713 for (Ice::SizeT ParamIndex = 0; ParamIndex < NumParams; ++ParamIndex) { | 2732 for (Ice::SizeT ParamIndex = 0; ParamIndex < NumParams; ++ParamIndex) { |
2714 Inst->addArg( | 2733 Ice::Operand *Op = |
2715 getRelativeOperand(Values[ParamsStartIndex + ParamIndex], BaseIndex)); | 2734 getRelativeOperand(Values[ParamsStartIndex + ParamIndex], BaseIndex); |
| 2735 if (Op == nullptr) { |
| 2736 std::string Buffer; |
| 2737 raw_string_ostream StrBuf(Buffer); |
| 2738 StrBuf << "Parameter " << ParamIndex << " of call not defined"; |
| 2739 Error(StrBuf.str()); |
| 2740 if (ReturnType != Ice::IceType_void) |
| 2741 appendErrorInstruction(ReturnType); |
| 2742 return; |
| 2743 } |
| 2744 |
| 2745 // Check that parameter type is valid. |
| 2746 if (Signature) { |
| 2747 if (Op->getType() != Signature->getArgType(ParamIndex)) { |
| 2748 std::string Buffer; |
| 2749 raw_string_ostream StrBuf(Buffer); |
| 2750 StrBuf << "Call argument " << *Op << " expects " |
| 2751 << Signature->getArgType(ParamIndex) |
| 2752 << ". Found: " << Op->getType(); |
| 2753 Error(StrBuf.str()); |
| 2754 } else if (IntrinsicInfo == nullptr && |
| 2755 !isCallParameterType(Op->getType())) { |
| 2756 // TODO(kschimpf): Move this check to the function declaration, so |
| 2757 // that it only needs to be checked once. |
| 2758 std::string Buffer; |
| 2759 raw_string_ostream StrBuf(Buffer); |
| 2760 StrBuf << "Call argument " << *Op |
| 2761 << " matches declaration but has invalid type: " |
| 2762 << Op->getType(); |
| 2763 Error(StrBuf.str()); |
| 2764 } |
| 2765 } else if (!isCallParameterType(Op->getType())) { |
| 2766 std::string Buffer; |
| 2767 raw_string_ostream StrBuf(Buffer); |
| 2768 StrBuf << "Call argument " << *Op |
| 2769 << " has invalid type: " << Op->getType(); |
| 2770 Error(StrBuf.str()); |
| 2771 } |
| 2772 Inst->addArg(Op); |
2716 } | 2773 } |
2717 | 2774 |
2718 // If intrinsic call, validate call signature. | 2775 // If intrinsic call, validate call signature. |
2719 if (IntrinsicInfo) { | 2776 if (IntrinsicInfo) { |
2720 Ice::SizeT ArgIndex = 0; | 2777 Ice::SizeT ArgIndex = 0; |
2721 switch (IntrinsicInfo->validateCall(Inst, ArgIndex)) { | 2778 switch (IntrinsicInfo->validateCall(Inst.get(), ArgIndex)) { |
2722 case Ice::Intrinsics::IsValidCall: | 2779 case Ice::Intrinsics::IsValidCall: |
2723 break; | 2780 break; |
2724 case Ice::Intrinsics::BadReturnType: { | 2781 case Ice::Intrinsics::BadReturnType: { |
2725 std::string Buffer; | 2782 std::string Buffer; |
2726 raw_string_ostream StrBuf(Buffer); | 2783 raw_string_ostream StrBuf(Buffer); |
2727 StrBuf << "Intrinsic call expects return type " | 2784 StrBuf << "Intrinsic call expects return type " |
2728 << IntrinsicInfo->getReturnType() | 2785 << IntrinsicInfo->getReturnType() |
2729 << ". Found: " << Inst->getReturnType(); | 2786 << ". Found: " << Inst->getReturnType(); |
2730 Error(StrBuf.str()); | 2787 Error(StrBuf.str()); |
2731 break; | 2788 break; |
(...skipping 11 matching lines...) Expand all Loading... |
2743 raw_string_ostream StrBuf(Buffer); | 2800 raw_string_ostream StrBuf(Buffer); |
2744 StrBuf << "Intrinsic call argument " << ArgIndex << " expects type " | 2801 StrBuf << "Intrinsic call argument " << ArgIndex << " expects type " |
2745 << IntrinsicInfo->getArgType(ArgIndex) | 2802 << IntrinsicInfo->getArgType(ArgIndex) |
2746 << ". Found: " << Inst->getArg(ArgIndex)->getType(); | 2803 << ". Found: " << Inst->getArg(ArgIndex)->getType(); |
2747 Error(StrBuf.str()); | 2804 Error(StrBuf.str()); |
2748 break; | 2805 break; |
2749 } | 2806 } |
2750 } | 2807 } |
2751 } | 2808 } |
2752 | 2809 |
2753 CurrentNode->appendInst(Inst); | 2810 CurrentNode->appendInst(Inst.release()); |
2754 return; | 2811 return; |
2755 } | 2812 } |
2756 case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF: { | 2813 case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF: { |
2757 // FORWARDTYPEREF: [opval, ty] | 2814 // FORWARDTYPEREF: [opval, ty] |
2758 if (!isValidRecordSize(2, "forward type ref")) | 2815 if (!isValidRecordSize(2, "forward type ref")) |
2759 return; | 2816 return; |
2760 Ice::Type OpType = Context->getSimpleTypeByID(Values[1]); | 2817 Ice::Type OpType = Context->getSimpleTypeByID(Values[1]); |
2761 setOperand(Values[0], | 2818 setOperand(Values[0], |
2762 isIRGenerationDisabled() ? nullptr : createInstVar(OpType)); | 2819 isIRGenerationDisabled() ? nullptr : createInstVar(OpType)); |
2763 return; | 2820 return; |
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3212 } | 3269 } |
3213 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { | 3270 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { |
3214 ErrStream | 3271 ErrStream |
3215 << IRFilename | 3272 << IRFilename |
3216 << ": Bitcode stream should be a multiple of 4 bytes in length.\n"; | 3273 << ": Bitcode stream should be a multiple of 4 bytes in length.\n"; |
3217 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); | 3274 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); |
3218 } | 3275 } |
3219 } | 3276 } |
3220 | 3277 |
3221 } // end of namespace Ice | 3278 } // end of namespace Ice |
OLD | NEW |