Mercurial > hg > truffle
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; |