comparison src/share/vm/opto/callGenerator.cpp @ 6894:a3ecd773a7b9

7184394: add intrinsics to use AES instructions Summary: Use new x86 AES instructions for AESCrypt. Reviewed-by: twisti, kvn, roland Contributed-by: tom.deneau@amd.com
author kvn
date Wed, 24 Oct 2012 14:33:22 -0700
parents e626685e9f6c
children beebba0acc11
comparison
equal deleted inserted replaced
6893:b2c669fd8114 6894:a3ecd773a7b9
668 } 668 }
669 return NULL; 669 return NULL;
670 } 670 }
671 671
672 672
673 //------------------------PredictedIntrinsicGenerator------------------------------
674 // Internal class which handles all predicted Intrinsic calls.
675 class PredictedIntrinsicGenerator : public CallGenerator {
676 CallGenerator* _intrinsic;
677 CallGenerator* _cg;
678
679 public:
680 PredictedIntrinsicGenerator(CallGenerator* intrinsic,
681 CallGenerator* cg)
682 : CallGenerator(cg->method())
683 {
684 _intrinsic = intrinsic;
685 _cg = cg;
686 }
687
688 virtual bool is_virtual() const { return true; }
689 virtual bool is_inlined() const { return true; }
690 virtual bool is_intrinsic() const { return true; }
691
692 virtual JVMState* generate(JVMState* jvms);
693 };
694
695
696 CallGenerator* CallGenerator::for_predicted_intrinsic(CallGenerator* intrinsic,
697 CallGenerator* cg) {
698 return new PredictedIntrinsicGenerator(intrinsic, cg);
699 }
700
701
702 JVMState* PredictedIntrinsicGenerator::generate(JVMState* jvms) {
703 GraphKit kit(jvms);
704 PhaseGVN& gvn = kit.gvn();
705
706 CompileLog* log = kit.C->log();
707 if (log != NULL) {
708 log->elem("predicted_intrinsic bci='%d' method='%d'",
709 jvms->bci(), log->identify(method()));
710 }
711
712 Node* slow_ctl = _intrinsic->generate_predicate(kit.sync_jvms());
713 if (kit.failing())
714 return NULL; // might happen because of NodeCountInliningCutoff
715
716 SafePointNode* slow_map = NULL;
717 JVMState* slow_jvms;
718 if (slow_ctl != NULL) {
719 PreserveJVMState pjvms(&kit);
720 kit.set_control(slow_ctl);
721 if (!kit.stopped()) {
722 slow_jvms = _cg->generate(kit.sync_jvms());
723 if (kit.failing())
724 return NULL; // might happen because of NodeCountInliningCutoff
725 assert(slow_jvms != NULL, "must be");
726 kit.add_exception_states_from(slow_jvms);
727 kit.set_map(slow_jvms->map());
728 if (!kit.stopped())
729 slow_map = kit.stop();
730 }
731 }
732
733 if (kit.stopped()) {
734 // Predicate is always false.
735 kit.set_jvms(slow_jvms);
736 return kit.transfer_exceptions_into_jvms();
737 }
738
739 // Generate intrinsic code:
740 JVMState* new_jvms = _intrinsic->generate(kit.sync_jvms());
741 if (new_jvms == NULL) {
742 // Intrinsic failed, so use slow code or make a direct call.
743 if (slow_map == NULL) {
744 CallGenerator* cg = CallGenerator::for_direct_call(method());
745 new_jvms = cg->generate(kit.sync_jvms());
746 } else {
747 kit.set_jvms(slow_jvms);
748 return kit.transfer_exceptions_into_jvms();
749 }
750 }
751 kit.add_exception_states_from(new_jvms);
752 kit.set_jvms(new_jvms);
753
754 // Need to merge slow and fast?
755 if (slow_map == NULL) {
756 // The fast path is the only path remaining.
757 return kit.transfer_exceptions_into_jvms();
758 }
759
760 if (kit.stopped()) {
761 // Intrinsic method threw an exception, so it's just the slow path after all.
762 kit.set_jvms(slow_jvms);
763 return kit.transfer_exceptions_into_jvms();
764 }
765
766 // Finish the diamond.
767 kit.C->set_has_split_ifs(true); // Has chance for split-if optimization
768 RegionNode* region = new (kit.C) RegionNode(3);
769 region->init_req(1, kit.control());
770 region->init_req(2, slow_map->control());
771 kit.set_control(gvn.transform(region));
772 Node* iophi = PhiNode::make(region, kit.i_o(), Type::ABIO);
773 iophi->set_req(2, slow_map->i_o());
774 kit.set_i_o(gvn.transform(iophi));
775 kit.merge_memory(slow_map->merged_memory(), region, 2);
776 uint tos = kit.jvms()->stkoff() + kit.sp();
777 uint limit = slow_map->req();
778 for (uint i = TypeFunc::Parms; i < limit; i++) {
779 // Skip unused stack slots; fast forward to monoff();
780 if (i == tos) {
781 i = kit.jvms()->monoff();
782 if( i >= limit ) break;
783 }
784 Node* m = kit.map()->in(i);
785 Node* n = slow_map->in(i);
786 if (m != n) {
787 const Type* t = gvn.type(m)->meet(gvn.type(n));
788 Node* phi = PhiNode::make(region, m, t);
789 phi->set_req(2, n);
790 kit.map()->set_req(i, gvn.transform(phi));
791 }
792 }
793 return kit.transfer_exceptions_into_jvms();
794 }
795
673 //-------------------------UncommonTrapCallGenerator----------------------------- 796 //-------------------------UncommonTrapCallGenerator-----------------------------
674 // Internal class which handles all out-of-line calls checking receiver type. 797 // Internal class which handles all out-of-line calls checking receiver type.
675 class UncommonTrapCallGenerator : public CallGenerator { 798 class UncommonTrapCallGenerator : public CallGenerator {
676 Deoptimization::DeoptReason _reason; 799 Deoptimization::DeoptReason _reason;
677 Deoptimization::DeoptAction _action; 800 Deoptimization::DeoptAction _action;