Path: blob/master/runtime/compiler/codegen/J9TreeEvaluator.hpp
6000 views
/*******************************************************************************1* Copyright (c) 2000, 2021 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20*******************************************************************************/2122#ifndef J9_TREE_EVALUATOR_INCL23#define J9_TREE_EVALUATOR_INCL2425/*26* The following #define and typedef must appear before any #includes in this file27*/28#ifndef J9_TREE_EVALUATOR_CONNECTOR29#define J9_TREE_EVALUATOR_CONNECTOR30namespace J9 { class TreeEvaluator; }31namespace J9 { typedef J9::TreeEvaluator TreeEvaluatorConnector; }32#endif3334#include "codegen/OMRTreeEvaluator.hpp"35#include "codegen/Snippet.hpp"3637namespace J938{3940class OMR_EXTENSIBLE TreeEvaluator: public OMR::TreeEvaluatorConnector41{42public:43enum InstanceOfOrCheckCastSequences44{45EvaluateCastClass,46LoadObjectClass,4748NullTest, // Needs object class: n, needs cast class: n49GoToTrue, // Needs object class: n, needs cast class: n50GoToFalse, // Needs object class: n, needs cast class: n51ProfiledClassTest, // Needs object class: y, needs cast class: n52CompileTimeGuessClassTest, // Needs object class: y, needs cast class: n53ArrayOfJavaLangObjectTest, // Needs object class: y, needs cast class: n54ClassEqualityTest, // Needs object class: y, needs cast class: y55SuperClassTest, // Needs object class: y, needs cast class: y56CastClassCacheTest, // Needs object class: y, needs cast class: y57DynamicCacheObjectClassTest, // Needs object class: y, needs cast class: n58DynamicCacheDynamicCastClassTest, // Needs object class: y, needs cast class: y59HelperCall, // Needs object class: n, needs cast class: y6061InstanceOfOrCheckCastMaxSequences62};6364/** \brief65* A structure containing following information66* 1. class67* 2. boolean representing if the class is instanceof cast class or not68* 3. probability69*/70struct InstanceOfOrCheckCastProfiledClasses71{72TR_OpaqueClassBlock *profiledClass;73bool isProfiledClassInstanceOfCastClass;74float frequency;75};7677static TR::Register *zdloadEvaluator(TR::Node *node, TR::CodeGenerator *cg);78static TR::Register *zdloadiEvaluator(TR::Node *node, TR::CodeGenerator *cg);79static TR::Register *zdstoreEvaluator(TR::Node *node, TR::CodeGenerator *cg);80static TR::Register *zdstoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg);81static TR::Register *pd2zdEvaluator(TR::Node *node, TR::CodeGenerator *cg);82static TR::Register *zd2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);83static TR::Register *zdsleLoadEvaluator(TR::Node *node, TR::CodeGenerator *cg);84static TR::Register *zdslsLoadEvaluator(TR::Node *node, TR::CodeGenerator *cg);85static TR::Register *zdstsLoadEvaluator(TR::Node *node, TR::CodeGenerator *cg);86static TR::Register *zdsleLoadiEvaluator(TR::Node *node, TR::CodeGenerator *cg);87static TR::Register *zdslsLoadiEvaluator(TR::Node *node, TR::CodeGenerator *cg);88static TR::Register *zdstsLoadiEvaluator(TR::Node *node, TR::CodeGenerator *cg);89static TR::Register *zdsleStoreEvaluator(TR::Node *node, TR::CodeGenerator *cg);90static TR::Register *zdslsStoreEvaluator(TR::Node *node, TR::CodeGenerator *cg);91static TR::Register *zdstsStoreEvaluator(TR::Node *node, TR::CodeGenerator *cg);92static TR::Register *zdsleStoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg);93static TR::Register *zdslsStoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg);94static TR::Register *zdstsStoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg);95static TR::Register *zd2zdsleEvaluator(TR::Node *node, TR::CodeGenerator *cg);96static TR::Register *zd2zdslsEvaluator(TR::Node *node, TR::CodeGenerator *cg);97static TR::Register *zd2zdstsEvaluator(TR::Node *node, TR::CodeGenerator *cg);98static TR::Register *zdsle2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);99static TR::Register *zdsls2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);100static TR::Register *zdsts2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);101static TR::Register *zdsle2zdEvaluator(TR::Node *node, TR::CodeGenerator *cg);102static TR::Register *zdsls2zdEvaluator(TR::Node *node, TR::CodeGenerator *cg);103static TR::Register *zdsts2zdEvaluator(TR::Node *node, TR::CodeGenerator *cg);104static TR::Register *pd2zdslsEvaluator(TR::Node *node, TR::CodeGenerator *cg);105static TR::Register *pd2zdslsSetSignEvaluator(TR::Node *node, TR::CodeGenerator *cg);106static TR::Register *pd2zdstsEvaluator(TR::Node *node, TR::CodeGenerator *cg);107static TR::Register *pd2zdstsSetSignEvaluator(TR::Node *node, TR::CodeGenerator *cg);108static TR::Register *udLoadEvaluator(TR::Node *node, TR::CodeGenerator *cg);109static TR::Register *udslLoadEvaluator(TR::Node *node, TR::CodeGenerator *cg);110static TR::Register *udstLoadEvaluator(TR::Node *node, TR::CodeGenerator *cg);111static TR::Register *udLoadiEvaluator(TR::Node *node, TR::CodeGenerator *cg);112static TR::Register *udslLoadiEvaluator(TR::Node *node, TR::CodeGenerator *cg);113static TR::Register *udstLoadiEvaluator(TR::Node *node, TR::CodeGenerator *cg);114static TR::Register *udStoreEvaluator(TR::Node *node, TR::CodeGenerator *cg);115static TR::Register *udslStoreEvaluator(TR::Node *node, TR::CodeGenerator *cg);116static TR::Register *udstStoreEvaluator(TR::Node *node, TR::CodeGenerator *cg);117static TR::Register *udStoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg);118static TR::Register *udslStoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg);119static TR::Register *udstStoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg);120static TR::Register *pd2udEvaluator(TR::Node *node, TR::CodeGenerator *cg);121static TR::Register *pd2udslEvaluator(TR::Node *node, TR::CodeGenerator *cg);122static TR::Register *pd2udstEvaluator(TR::Node *node, TR::CodeGenerator *cg);123static TR::Register *udsl2udEvaluator(TR::Node *node, TR::CodeGenerator *cg);124static TR::Register *udst2udEvaluator(TR::Node *node, TR::CodeGenerator *cg);125static TR::Register *ud2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);126static TR::Register *udsl2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);127static TR::Register *udst2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);128static TR::Register *pdloadEvaluator(TR::Node *node, TR::CodeGenerator *cg);129static TR::Register *pdloadiEvaluator(TR::Node *node, TR::CodeGenerator *cg);130static TR::Register *pdstoreEvaluator(TR::Node *node, TR::CodeGenerator *cg);131static TR::Register *pdstoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg);132static TR::Register *pdaddEvaluator(TR::Node *node, TR::CodeGenerator *cg);133static TR::Register *pdsubEvaluator(TR::Node *node, TR::CodeGenerator *cg);134static TR::Register *pdmulEvaluator(TR::Node *node, TR::CodeGenerator *cg);135static TR::Register *pddivEvaluator(TR::Node *node, TR::CodeGenerator *cg);136static TR::Register *pdremEvaluator(TR::Node *node, TR::CodeGenerator *cg);137static TR::Register *pdnegEvaluator(TR::Node *node, TR::CodeGenerator *cg);138static TR::Register *pdabsEvaluator(TR::Node *node, TR::CodeGenerator *cg);139static TR::Register *pdshrEvaluator(TR::Node *node, TR::CodeGenerator *cg);140static TR::Register *pdshlEvaluator(TR::Node *node, TR::CodeGenerator *cg);141static TR::Register *pdshrSetSignEvaluator(TR::Node *node, TR::CodeGenerator *cg);142static TR::Register *pdshlSetSignEvaluator(TR::Node *node, TR::CodeGenerator *cg);143static TR::Register *pdshlOverflowEvaluator(TR::Node *node, TR::CodeGenerator *cg);144static TR::Register *pdchkEvaluator(TR::Node *node, TR::CodeGenerator *cg);145static TR::Register *pd2iEvaluator(TR::Node *node, TR::CodeGenerator *cg);146static TR::Register *pd2iuEvaluator(TR::Node *node, TR::CodeGenerator *cg);147static TR::Register *pd2iOverflowEvaluator(TR::Node *node, TR::CodeGenerator *cg);148static TR::Register *i2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);149static TR::Register *iu2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);150static TR::Register *pd2lEvaluator(TR::Node *node, TR::CodeGenerator *cg);151static TR::Register *pd2luEvaluator(TR::Node *node, TR::CodeGenerator *cg);152static TR::Register *pd2lOverflowEvaluator(TR::Node *node, TR::CodeGenerator *cg);153static TR::Register *l2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);154static TR::Register *lu2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);155static TR::Register *pd2fEvaluator(TR::Node *node, TR::CodeGenerator *cg);156static TR::Register *pd2dEvaluator(TR::Node *node, TR::CodeGenerator *cg);157static TR::Register *f2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);158static TR::Register *d2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);159static TR::Register *pdcmpeqEvaluator(TR::Node *node, TR::CodeGenerator *cg);160static TR::Register *pdcmpneEvaluator(TR::Node *node, TR::CodeGenerator *cg);161static TR::Register *pdcmpltEvaluator(TR::Node *node, TR::CodeGenerator *cg);162static TR::Register *pdcmpgeEvaluator(TR::Node *node, TR::CodeGenerator *cg);163static TR::Register *pdcmpgtEvaluator(TR::Node *node, TR::CodeGenerator *cg);164static TR::Register *pdcmpleEvaluator(TR::Node *node, TR::CodeGenerator *cg);165static TR::Register *pdcleanEvaluator(TR::Node *node, TR::CodeGenerator *cg);166static TR::Register *pdclearEvaluator(TR::Node *node, TR::CodeGenerator *cg);167static TR::Register *pdclearSetSignEvaluator(TR::Node *node, TR::CodeGenerator *cg);168static TR::Register *pdSetSignEvaluator(TR::Node *node, TR::CodeGenerator *cg);169static TR::Register *pdModifyPrecisionEvaluator(TR::Node *node, TR::CodeGenerator *cg);170static TR::Register *countDigitsEvaluator(TR::Node *node, TR::CodeGenerator *cg);171static TR::Register *BCDCHKEvaluator(TR::Node *node, TR::CodeGenerator *cg);172173static uint32_t calculateInstanceOfOrCheckCastSequences(TR::Node *instanceOfOrCheckCastNode, InstanceOfOrCheckCastSequences *sequences, TR_OpaqueClassBlock **compileTimeGuessClass, TR::CodeGenerator *cg, InstanceOfOrCheckCastProfiledClasses *profiledClassList, uint32_t *numberOfProfiledClass, uint32_t maxProfileClass, float *topClassProbability, bool *topClassWasCastClass);174175static uint8_t interpreterProfilingInstanceOfOrCheckCastInfo(TR::CodeGenerator * cg, TR::Node * node, TR_OpaqueClassBlock **classArray, float* probability=NULL, bool recordAll = false);176177static TR_OpaqueClassBlock* interpreterProfilingInstanceOfOrCheckCastInfo(TR::CodeGenerator * cg, TR::Node * node);178179static bool checkcastShouldOutlineSuperClassTest(TR::Node *castClassNode, TR::CodeGenerator *cg);180181static bool loadLookaheadAfterHeaderAccess(TR::Node *node, int32_t &fieldOffset, TR::CodeGenerator *cg);182183static bool instanceOfNeedHelperCall(bool testCastClassIsSuper, bool isFinalClass);184185static bool instanceOfOrCheckCastIsJavaLangObjectArray(TR::Node * castClassNode, TR::CodeGenerator *cg);186static TR_OpaqueClassBlock * getCastClassAddress(TR::Node * castClassNode);187static bool instanceOfOrCheckCastIsFinalArray(TR::Node * castClassNode, TR::CodeGenerator *cg);188189static TR::Register *bwrtbarEvaluator(TR::Node *node, TR::CodeGenerator *cg);190static TR::Register *bwrtbariEvaluator(TR::Node *node, TR::CodeGenerator *cg);191static TR::Register *swrtbarEvaluator(TR::Node *node, TR::CodeGenerator *cg);192static TR::Register *swrtbariEvaluator(TR::Node *node, TR::CodeGenerator *cg);193static TR::Register *iwrtbarEvaluator(TR::Node *node, TR::CodeGenerator *cg);194static TR::Register *iwrtbariEvaluator(TR::Node *node, TR::CodeGenerator *cg);195static TR::Register *lwrtbarEvaluator(TR::Node *node, TR::CodeGenerator *cg);196static TR::Register *lwrtbariEvaluator(TR::Node *node, TR::CodeGenerator *cg);197198static TR::Register *frdbarEvaluator(TR::Node *node, TR::CodeGenerator *cg);199static TR::Register *frdbariEvaluator(TR::Node *node, TR::CodeGenerator *cg);200static TR::Register *drdbarEvaluator(TR::Node *node, TR::CodeGenerator *cg);201static TR::Register *drdbariEvaluator(TR::Node *node, TR::CodeGenerator *cg);202static TR::Register *brdbarEvaluator(TR::Node *node, TR::CodeGenerator *cg);203static TR::Register *brdbariEvaluator(TR::Node *node, TR::CodeGenerator *cg);204static TR::Register *srdbarEvaluator(TR::Node *node, TR::CodeGenerator *cg);205static TR::Register *srdbariEvaluator(TR::Node *node, TR::CodeGenerator *cg);206static TR::Register *lrdbarEvaluator(TR::Node *node, TR::CodeGenerator *cg);207static TR::Register *lrdbariEvaluator(TR::Node *node, TR::CodeGenerator *cg);208static TR::Register *monexitfenceEvaluator(TR::Node *node, TR::CodeGenerator *cg);209210/*211* \brief212* Invokes the sequence of codegen routines to report the watched field.213*/214static void rdWrtbarHelperForFieldWatch(TR::Node *node, TR::CodeGenerator *cg, TR::Register *sideEffectRegister, TR::Register *valueReg);215/*216* \brief217* Populates and Returns the FieldWatchStaticSnippet corresponding to the specific codegen.218*/219static TR::Snippet *getFieldWatchStaticSnippet(TR::CodeGenerator *cg, TR::Node *node, J9Method *m, UDATA loc, void *fieldAddress, J9Class *fieldClass);220/*221* \brief222* Populates and Returns the FieldWatchInstanceSnippet corresponding to the specific codegen.223*/224static TR::Snippet *getFieldWatchInstanceSnippet(TR::CodeGenerator *cg, TR::Node *node, J9Method *m, UDATA loc, UDATA os);225/*226* \brief227* Sets the node representing the value to be written for an indirect wrtbar. Returns228* true/false if the correct pattern was found (i.e. if compressedReferences is being used).229*230* \note231* For address type nodes using compressedrefs, the compressed refs sequence is skipped232* from the sub tree and the uncompressed address value is set to sourceChild.233* For all other cases, sourceChild is set to the secondChild.234*/235static bool getIndirectWrtbarValueNode(TR::CodeGenerator *cg, TR::Node *node, TR::Node*& sourceChild, bool incSrcRefCount);236static void evaluateLockForReservation(TR::Node *node, bool *reservingLock, bool *normalLockPreservingReservation, TR::CodeGenerator *cg);237static bool isPrimitiveMonitor (TR::Node *node, TR::CodeGenerator *cg);238static bool isDummyMonitorEnter (TR::Node *node, TR::CodeGenerator *cg);239static bool isDummyMonitorExit (TR::Node *node, TR::CodeGenerator *cg);240241static void preEvaluateEscapingNodesForSpineCheck(TR::Node *root, TR::CodeGenerator *cg);242243static TR::Register *resolveCHKEvaluator(TR::Node *node, TR::CodeGenerator *cg);244245/*246* \brief247* Checks if inline allocation is allowed when value type is enabled.248* The helper call is required if the first child of the "new" node, the class node, is a value type class249* but it tries to create a non-value type instance, or if the class node is non-value type class but it250* tries to create a value type instance.251*/252static bool requireHelperCallValueTypeAllocation(TR::Node *node, TR::CodeGenerator *cg);253};254255}256257#endif258259260