Path: blob/master/runtime/compiler/il/J9Node.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_NODE_INCL23#define J9_NODE_INCL2425/*26* The following #define and typedef must appear before any #includes in this file27*/28#ifndef J9_NODE_CONNECTOR29#define J9_NODE_CONNECTOR30namespace J9 { class Node; }31namespace J9 { typedef J9::Node NodeConnector; }32#endif3334#include "j9cfg.h"35#include "il/OMRNode.hpp"3637class TR_OpaquePseudoRegister;38class TR_StorageReference;39class TR_PseudoRegister;40namespace TR { class Compilation; }41namespace TR { class Node; }42namespace TR { class ResolvedMethodSymbol; }43namespace TR { class TreeTop; }4445namespace J9 {4647class OMR_EXTENSIBLE Node : public OMR::NodeConnector48{4950protected:5152Node(TR::Node *originatingByteCodeNode, TR::ILOpCodes op, uint16_t numChildren);5354Node(TR::Node *from, uint16_t numChildren = 0);5556Node(Node& from) : OMR::NodeConnector(from) {}575859public:6061Node()62: OMR::NodeConnector(),63_unionPropertyB()64{ }6566~Node();6768static void copyValidProperties(TR::Node *fromNode, TR::Node *toNode);6970uint32_t getSize();7172bool dontEliminateStores(bool isForLocalDeadStore = false);7374/// given a direct call to Object.clone node, return the class of the receiver.75///76TR_OpaqueClassBlock* getCloneClassInNode();77TR::Node * processJNICall(TR::TreeTop *, TR::ResolvedMethodSymbol *);7879void devirtualizeCall(TR::TreeTop*);8081/**82* @return the signature of the node's type if applicable.83* @note the signature's storage may have been created on the stack!84*/85const char * getTypeSignature(int32_t &, TR_AllocationKind = stackAlloc, bool parmAsAuto = false);8687#if defined(TR_TARGET_S390)88TR_PseudoRegister *getPseudoRegister();89TR_OpaquePseudoRegister *getOpaquePseudoRegister();90#endif9192/**93* @brief Answers whether the act of evaluating this node will94* require a register pair (two registers) to hold the95* result.96* @param comp, the TR::Compilation object97* @return true if two registers are required; false otherwise98*/99bool requiresRegisterPair(TR::Compilation *comp);100101TR::Node *getSetSignValueNode();102void setKnownSignCodeFromRawSign(int32_t rawSignCode);103static bool typeSupportedForTruncateOrWiden(TR::DataType dt);104static bool typeSupportedForSignCodeTracking(TR::DataType dt);105static void truncateOrWidenBCDLiteral(TR::DataType dt, char *newLit, int32_t newPrecision, char *oldLit, int32_t oldPrecision);106static void setNewBCDSignOnLiteral(uint32_t newSignCode, TR::DataType dt, char *lit, int32_t litSize);107108bool alwaysGeneratesAKnownCleanSign();109bool alwaysGeneratesAKnownPositiveCleanSign();110#ifdef TR_TARGET_S390111int32_t getStorageReferenceSize();112int32_t getStorageReferenceSourceSize();113#endif114115bool isEvenPrecision();116bool isOddPrecision();117bool pdshrRoundIsConstantZero();118119bool isSimpleTruncation();120bool isSimpleWidening();121bool mustClean();122bool hasIntermediateTruncation();123bool isTruncatingBCDShift();124bool isWideningBCDShift();125bool isTruncating();126int32_t survivingDigits();127128129130bool isTruncatingOrWideningAggrOrBCD();131132bool canRemoveArithmeticOperand();133bool canGCandReturn();134135static uint32_t hashOnBCDOrAggrLiteral(char *lit, size_t litSize);136137bool referencesSymbolInSubTree(TR::SymbolReference * symRef, vcount_t visitCount);138bool referencesMayKillAliasInSubTree(TR::Node * rootNode, vcount_t visitCount);139void getSubTreeReferences(TR::SparseBitVector &references, vcount_t visitCount);140TR_ParentOfChildNode * referencesSymbolExactlyOnceInSubTree(TR::Node *, int32_t, TR::SymbolReference *, vcount_t);141142/**143* Node field functions144*/145146#ifdef TR_TARGET_S390147TR_StorageReference *getStorageReferenceHint();148TR_StorageReference *setStorageReferenceHint(TR_StorageReference *s);149#endif150151/**152* Node field functions end153*/154155156157/**158* UnionPropertyB functions159*/160161void setDecimalPrecision(int32_t p);162uint8_t getDecimalPrecision();163164// These precision setting routines set a precision big enough to hold the165// full computed result A caller or codegen may choose to set a different166// value (bigger or smaller) to satisfy a specific semantic or encoding167// requirement -- see getPDMulEncodedPrecision et al. in the platform code168// generators169void setPDMulPrecision();170void setPDAddSubPrecision();171172void setDecimalAdjust(int32_t a);173int32_t getDecimalAdjust();174175void setDecimalFraction(int32_t f);176int32_t getDecimalFraction();177178// Source precisions are valid for conversions from a non-BCD type to a BCD type179bool canHaveSourcePrecision();180bool hasSourcePrecision();181void setSourcePrecision(int32_t prec);182int32_t getSourcePrecision();183184int32_t getDecimalAdjustOrFractionOrDivisor();185int32_t getDecimalRoundOrDividend();186187bool isSetSignValueOnNode();188void setSetSign(TR_RawBCDSignCode setSign);189TR_RawBCDSignCode getSetSign();190bool isDecimalSizeAndShapeEquivalent(TR::Node *other);191192void setDecimalRound(int32_t r);193uint8_t getDecimalRound();194195bool signStateIsKnown();196void setSignStateIsKnown();197bool signStateIsAssumed();198void setSignStateIsAssumed();199200bool hasKnownCleanSign();201void setHasKnownCleanSign(bool v);202bool hasAssumedCleanSign();203void setHasAssumedCleanSign(bool v);204bool hasKnownOrAssumedCleanSign();205void setHasKnownAndAssumedCleanSign(bool v);206void transferCleanSign(TR::Node *srcNode);207208bool hasKnownPreferredSign();209void setHasKnownPreferredSign(bool v);210bool hasAssumedPreferredSign();211void setHasAssumedPreferredSign(bool v);212bool hasKnownOrAssumedPreferredSign();213214bool hasKnownSignCode();215TR_RawBCDSignCode getKnownSignCode();216bool hasAssumedSignCode();217TR_RawBCDSignCode getAssumedSignCode();218bool hasKnownOrAssumedSignCode();219TR_RawBCDSignCode getKnownOrAssumedSignCode();220void setKnownOrAssumedSignCode(TR_RawBCDSignCode sign, bool isKnown);221void setKnownSignCode(TR_RawBCDSignCode sign);222void transferSignCode(TR::Node *srcNode);223224// The mapping to/from TR_BCDSignCode from/to the 0xc/0xd/0xf 'raw'225// encodings in setKnownSignCode/knownSignCodeIs below // is temporary until226// TR_BCDSignCode is tracked on the nodes instead of TR_RawBCDSignCode227// Doing it this way allows new code (such as VP constrainBCDAggrLoad) to228// start using this new more general interface // The final code will be just229// calling setKnownOrAssumedSignCode(sign, true, c) but now the 'sign' parm will230// be TR_BCDSignCode of TR_RawBCDSignCode231bool knownSignCodeIs(TR_BCDSignCode sign);232void setKnownSignCode(TR_BCDSignCode sign);233bool assumedSignCodeIs(TR_BCDSignCode sign);234void setAssumedSignCode(TR_RawBCDSignCode sign);235bool knownOrAssumedSignCodeIs(TR_BCDSignCode sign);236237// the hasSignState property is stored in the reverse sense to make the interface easier to use (at the expense of some confusion here);238bool hasSignStateOnLoad();239void setHasSignStateOnLoad(bool v);240241void transferSignState(TR::Node *srcNode, bool digitsLost);242bool hasAnyKnownOrAssumedSignState();243bool hasAnyDecimalSignState();244void resetDecimalSignFlags();245void resetSignState();246247bool isSignStateEquivalent(TR::Node *other);248bool isSignStateAnImprovementOver(TR::Node *other);249250bool chkOpsCastedToBCD();251bool castedToBCD();252void setCastedToBCD(bool v);253254/**255* UnionPropertyB functions end256*/257258259260/**261* Node flag functions262*/263264// Flag used by TR::BNDCHK nodes265bool isSpineCheckWithArrayElementChild();266void setSpineCheckWithArrayElementChild(bool v);267bool chkSpineCheckWithArrayElementChild();268const char *printSpineCheckWithArrayElementChild();269270// Flags used by call nodes271bool isUnsafePutOrderedCall();272bool isDontInlinePutOrderedCall();273void setDontInlinePutOrderedCall();274bool chkDontInlineUnsafePutOrderedCall();275const char * printIsDontInlineUnsafePutOrderedCall();276277/**278* Checks and return true if the callNode is JNI Call to Unsafe.copyMemory279*/280bool isUnsafeCopyMemoryIntrinsic();281282bool isUnsafeGetPutCASCallOnNonArray();283void setUnsafeGetPutCASCallOnNonArray();284285bool isProcessedByCallCloneConstrain();286void setProcessedByCallCloneConstrain();287288bool isDAAVariableSlowCall();289void setDAAVariableSlowCall(bool v);290291// Flag used by binary coded decimal load nodes292bool isBCDStoreTemporarilyALoad();293void setBCDStoreIsTemporarilyALoad(bool v);294295// Flag used by isPackedLeftShift nodes296bool cleanSignDuringPackedLeftShift();297void setCleanSignDuringPackedLeftShift(bool v);298bool chkCleanSignDuringPackedLeftShift();299const char *printCleanSignDuringPackedLeftShift();300301// Flag used by non-store and non-call binary coded decimal and aggregate nodes302bool chkOpsSkipCopyOnLoad();303bool skipCopyOnLoad();304void setSkipCopyOnLoad(bool v);305bool chkSkipCopyOnLoad();306const char *printSkipCopyOnLoad();307308// Flag used by binary coded decimal and aggregate store nodes309bool chkOpsSkipCopyOnStore();310bool skipCopyOnStore();311void setSkipCopyOnStore(bool v);312bool chkSkipCopyOnStore();313const char *printSkipCopyOnStore();314315// Flag used by packed decimal stores316bool chkOpsCleanSignInPDStoreEvaluator();317bool mustCleanSignInPDStoreEvaluator();318void setCleanSignInPDStoreEvaluator(bool v);319bool chkCleanSignInPDStoreEvaluator();320const char *printCleanSignInPDStoreEvaluator();321322// Flag used by binary coded decimal stores and aggregate stores323bool chkOpsUseStoreAsAnAccumulator();324bool useStoreAsAnAccumulator();325void setUseStoreAsAnAccumulator(bool v);326bool chkUseStoreAsAnAccumulator();327const char *printUseStoreAsAnAccumulator();328329// Flag used by non-store packed types330bool canSkipPadByteClearing();331void setSkipPadByteClearing(bool v);332bool chkSkipPadByteClearing();333const char *printSkipPadByteClearing();334335// Flag used for BCD and Aggr type stores336bool chkOpsIsInMemoryCopyProp();337bool isInMemoryCopyProp();338void setIsInMemoryCopyProp(bool v);339bool chkIsInMemoryCopyProp();340const char *printIsInMemoryCopyProp();341342// Flag used by address type nodes in Java343bool chkSharedMemory();344void setSharedMemory(bool v);345const char *printSharedMemory();346347348bool isArrayCopyCall();349350/**351* Node flag functions end352*/353354inline float getFloat();355inline float setFloat(float f);356357#ifdef J9VM_OPT_JAVA_CRYPTO_ACCELERATION358bool processJNICryptoMethodCall(TR::ResolvedMethodSymbol *methodSymbol, TR::Compilation *comp);359#endif360361protected:362363/// \note update the following routines when adding field to DecimalInfo364/// isDecimalSizeAndShapeEquivalent()365/// isSignStateEquivalent()366/// resetDecimalSignFlags()367/// transferSignState()368/// Also be sure to initialize any new field in the Node.cpp constructor369struct DecimalInfo370{371uint32_t _decimalPrecision : 6; ///< range 0->63372int32_t _decimalAdjustOrFractionOrDivisor : 7; ///< range as Adjust -63->63 (on all except conversion nodes)373///< range as Fraction -63->63 (only on isConversionWithFraction nodes)374///< range as divisorPrecision 0->63 (on select nodes)375///< range as extFloatSrcIntDigits 0->63 (but should only need 16, on extFloat to other conversions, e.g. zf2uf,zf2d)376uint32_t _decimalSourcePrecisionOrDividend : 6; ///< range as source precision (on non-BCD-to-BCD conversions) 0->63, as dividendPrecision 0->63 (on select nodes)377TR_RawBCDSignCode _setSign : 3; ///< range on isSetSign opcodes378uint32_t _signStateIsKnown : 1; ///< true (known) or false (assumed)379uint32_t _hasCleanSign : 1; ///< true/false380uint32_t _hasPreferredSign : 1; ///< true/false381uint32_t _round : 1; ///< true/false382uint32_t _hasNoSignStateOnLoad : 1; ///< true/false // for BCD loads : false for PRE created loads that must preserve sign state (conservative setting), true for FE created loads383uint32_t _castedToBCD : 1; ///< true/false // if true node was not originally a BCD type but casted to BCD by the optimizer from a non-BCD type (e.g. aggr or int)384TR_RawBCDSignCode _signCode : 3;385};386387// keep nodes as small as possible for frontends that do not need the data below388// The fields below are all disjoint, which fields exist for which platforms/opcodes are provided by the given has<Field> functions389union UnionPropertyB390{391// field exists when following is true: only one of these should be true for a given node392// eventually should replace by exclusive representation (eg. enum)393DecimalInfo _decimalInfo; ///< hasDecimalInfo()394// overflow/rounding option395UnionPropertyB()396{397memset(this, 0, sizeof(UnionPropertyB)); ///< in C++11 notation: _unionPropertyB = {0};398}399};400401enum UnionPropertyB_Type402{403HasNoUnionPropertyB = 0,404HasDecimalInfo, ///< hasDecimalInfo()405HasBcdFlags ///< hasBCDFlags()406};407408bool hasDecimalInfo();409bool hasBCDFlags();410UnionPropertyB_Type getUnionPropertyB_Type();411412// for DecimalInfo subtypes413bool hasDecimalPrecision();414bool hasDecimalAdjust();415bool hasSetSign();416bool hasDecimalFraction();417bool hasDecimalRound();418419// Fields420private:421422#ifdef TR_TARGET_S390423///< hasStorageReferenceHint()424TR_StorageReference * _storageReferenceHint;425#endif426427// Holds DecimalInfo and BCDFlags428UnionPropertyB _unionPropertyB;429430protected:431// Flag bits432enum433{434// Flag used by TR::BNDCHK nodes435spineCHKWithArrayElementChild = 0x00004000,436437// Flags used by call nodes438dontInlineUnsafePutOrderedCall = 0x00000800, ///< unsafe putOrdered calls439processedByCallCloneConstrain = 0x00100000,440unsafeGetPutOnNonArray = 0x00200000,441DAAVariableSlowCall = 0x00400000, ///< Used to avoid Variable precision DAA optimization442443// Flag used by binary coded decimal load nodes444IsBCDStoreTemporarilyALoad = 0x00400000,445446// Flag used by isPackedLeftShift nodes (pdshl,pdshlSetSign...)447CleanSignDuringPackedLeftShift = 0x00400000,448449// Flag used by non-store and non-call binary coded decimal and aggregate nodes450SkipCopyOnLoad = 0x00800000,451452// Flag used by binary coded decimal and aggregate store nodes453SkipCopyOnStore = 0x00080000,454455// Flag used by packed decimal stores (eg pdstore/ipdstore)456cleanSignInPDStoreEvaluator = 0x00040000,457458// Flag used by binary coded decimal stores and aggregate stores (eg pdstore/ipdstore/zdstore/izdstore etc)459// (all nodes where ILProp3::CanUseStoreAsAnAccumulator is set)460UseStoreAsAnAccumulator = 0x00200000,461462// Flag used by non-store packed types463skipPadByteClearing = 0x00020000,464465// Flag used by BCD and Aggr type stores -- for in memory types set when 1 or more child of the store was changed466// during local or global copy propagation467IsInMemoryCopyProp = 0x08000000,468469// Flag used by address type nodes in Java470sharedMemory = 0x00000400,471472};473474};475476}477478#endif479480481482