blob: 5f58909ada5820097130de6452813031170bd112 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Intel, Pavel A. Ozhdikhin
*
*/
#ifndef _INST_H_
#define _INST_H_
#include "MemoryManager.h"
#include "Stl.h"
#include "VMInterface.h"
#include "Dlink.h"
#include "Type.h"
#include "Opcode.h"
#include "Opnd.h"
#include "Log.h"
#include "ControlFlowGraph.h"
#include "open/types.h"
#include <assert.h>
#include <stdio.h>
#include <iostream>
namespace Jitrino {
class OpndRenameTable;
class IRBuilder;
class IRManager;
class InstFactory;
class PiCondition;
class DominatorTree;
//
// forward declarations of the different instruction formats
//
class Inst;
class LabelInst;
class DispatchLabelInst;
class CatchLabelInst;
class MethodEntryInst;
class MethodMarkerInst;
class TypeInst;
class VarAccessInst;
class FieldAccessInst;
class BranchInst;
class SwitchInst;
class ConstInst;
class MethodInst;
class TokenInst;
class LinkingExcInst;
class CallInst;
class JitHelperCallInst;
class VMHelperCallInst;
class PhiInst;
class MultiSrcInst;
class MethodCallInst;
class TauPiInst;
//
// visitor pattern for the different instruction formats
//
class InstFormatVisitor {
public:
virtual ~InstFormatVisitor() {}
virtual void accept(Inst*) = 0;
virtual void accept(BranchInst*) = 0;
virtual void accept(CallInst*) = 0;
virtual void accept(CatchLabelInst*) = 0;
virtual void accept(ConstInst*) = 0;
virtual void accept(DispatchLabelInst*) = 0;
virtual void accept(JitHelperCallInst*) = 0;
virtual void accept(VMHelperCallInst*) = 0;
virtual void accept(FieldAccessInst*) = 0;
virtual void accept(LabelInst*) = 0;
virtual void accept(MethodCallInst*) = 0;
virtual void accept(MethodEntryInst*) = 0;
virtual void accept(MethodInst*) = 0;
virtual void accept(MethodMarkerInst*) = 0;
virtual void accept(MultiSrcInst*) = 0;
virtual void accept(PhiInst*) = 0;
virtual void accept(TauPiInst*) = 0;
virtual void accept(SwitchInst*) = 0;
virtual void accept(TokenInst*) = 0;
virtual void accept(TypeInst*) = 0;
virtual void accept(VarAccessInst*) = 0;
};
//
// Base Instruction class.
//
#define MAX_INST_SRCS 2
class Inst : public CFGInst {
public:
virtual ~Inst() {}
Inst* getNextInst() const {return (Inst*)next();}
Inst* getPrevInst() const {return (Inst*)prev();}
bool isHeaderCriticalInst() const {return getOpcode() == Op_Catch || isLabel();}
Type::Tag getType() const {
return operation.getType();
}
Opcode getOpcode() const {
return operation.getOpcode();
}
Modifier getModifier() const {
return operation.getModifier();
}
Operation getOperation() const {return operation;}
U_32 getId() const {return id;}
PersistentInstructionId getPersistentInstructionId() const {return pid; }
void setPersistentInstructionId(PersistentInstructionId id) {pid = id; }
Opnd* getDst() const {return dst;}
void setType(Type::Tag newType) {
operation.setType(newType);
}
void setModifier(Modifier newMod) {
operation.setModifier(newMod);
}
void setDst(Opnd* newDst) {
if (dst && dst->isNull() == false && dst->isVarOpnd() == false && (dst->getInst() == this))
dst->setInst(0);
dst = newDst;
if (dst && dst->isNull() == false && dst->isVarOpnd() == false)
dst->setInst(this);
}
U_32 getNumSrcOperands() const {return numSrcs;}
Opnd* getSrc(U_32 srcIndex) const {
assert(srcIndex < numSrcs);
if (srcIndex >= MAX_INST_SRCS)
return getSrcExtended(srcIndex);
return srcs[srcIndex];
}
void setSrc(U_32 srcIndex, Opnd* src) {
assert(srcIndex < numSrcs);
if (srcIndex >= MAX_INST_SRCS)
setSrcExtended(srcIndex, src);
else
srcs[srcIndex] = src;
}
virtual void visit(InstFormatVisitor& visitor) {visitor.accept(this);}
//
// for down-casting to a derived Inst class
// we de-virtualize these so the C++ compiler can do CSE on isFoo() in most uses
//
BranchInst* asBranchInst() const {
if (isBranch()) return (BranchInst*)this; else return NULL;
}
CallInst* asCallInst() const {
if (isCall()) return (CallInst*)this; else return NULL;
}
CatchLabelInst* asCatchLabelInst() const {
if (isCatchLabel()) return (CatchLabelInst*)this; else return NULL;
}
ConstInst* asConstInst() const {
if (isConst()) return (ConstInst*)this; else return NULL;
}
DispatchLabelInst* asDispatchLabelInst() const {
if (isDispatchLabel()) return (DispatchLabelInst*)this; else return NULL;
}
FieldAccessInst* asFieldAccessInst() const {
if (isFieldAccess()) return (FieldAccessInst*)this; else return NULL;
}
JitHelperCallInst* asJitHelperCallInst() const {
if (isJitHelperCallInst()) return (JitHelperCallInst*) this; else return NULL;
}
VMHelperCallInst* asVMHelperCallInst() const {
if (isVMHelperCallInst()) return (VMHelperCallInst*) this; else return NULL;
}
LabelInst* asLabelInst() const {
if (isLabel()) return (LabelInst*)this; else return NULL;
}
MethodCallInst* asMethodCallInst() const {
if (isMethodCall()) return (MethodCallInst*)this; else return NULL;
}
MethodEntryInst* asMethodEntryInst() const {
if (isMethodEntry()) return (MethodEntryInst*)this; else return NULL;
}
MethodInst* asMethodInst() const {
if (isMethod()) return (MethodInst*)this; else return NULL;
}
MethodMarkerInst* asMethodMarkerInst() const {
if (isMethodMarker()) return(MethodMarkerInst*)this; else return NULL;
}
MultiSrcInst* asMultiSrcInst() const {
if (isMultiSrcInst()) return (MultiSrcInst*)this; else return NULL;
}
PhiInst* asPhiInst() const {
if (isPhi()) return (PhiInst*)this; else return NULL;
}
TauPiInst *asTauPiInst() const {
if (isTauPi()) return (TauPiInst*)this; else return NULL;
}
SwitchInst* asSwitchInst() const {
if (isSwitch()) return (SwitchInst *)this; else return NULL;
}
TokenInst* asTokenInst() const {
if (isToken()) return (TokenInst*)this; else return NULL;
}
TypeInst* asTypeInst() const {
if (isType()) return (TypeInst*) this; else return NULL;
}
VarAccessInst* asVarAccessInst() const {
if (isVarAccess()) return (VarAccessInst*) this; else return NULL;
}
void print(::std::ostream&) const;
bool isSigned() const {
return operation.isSigned();
}
virtual bool isBranch() const { return false; };
virtual bool isCall() const { return false; };
virtual bool isCatchLabel() const { return false; };
virtual bool isConst() const { return false; };
virtual bool isDispatchLabel() const { return false; };
virtual bool isFieldAccess() const { return false; };
virtual bool isJitHelperCallInst() const { return false; };
virtual bool isVMHelperCallInst() const { return false; };
virtual bool isMethodCall() const { return false; };
virtual bool isMethodEntry() const { return false; };
virtual bool isMethod() const { return false; };
virtual bool isMethodMarker() const { return false; };
virtual bool isMultiSrcInst() const { return false; };
bool isPhi() const { return (getOpcode() == Op_Phi); };
bool isTauPi() const { return (getOpcode() == Op_TauPi); };
bool isSwitch() const { return (getOpcode() == Op_Switch); };
virtual bool isToken() const { return false; };
virtual bool isType() const { return false; };
virtual bool isVarAccess() const { return false; };
bool isThrow() const ;
bool isReturn() const {return getOpcode() == Op_Return; }
bool isLdVar() const {return getOpcode() == Op_LdVar; }
bool isLdVarAddr() const {return getOpcode() == Op_LdVarAddr; }
bool isStVar() const {return getOpcode() == Op_StVar; }
bool isJSR() const {return getOpcode() == Op_JSR; }
bool isRet() const {return getOpcode() == Op_Ret; }
bool isUnconditionalBranch() const {return getOpcode() == Op_Jump;}
bool isConditionalBranch() const {return getOpcode() == Op_Branch;}
ComparisonModifier getComparisonModifier() const {
return operation.getComparisonModifier();
}
void setComparisonModifier(ComparisonModifier newmod) {
operation.setComparisonModifier(newmod);
}
SignedModifier getSignedModifier() const {
return operation.getSignedModifier();
}
void setSignedModifier(SignedModifier newmod) {
operation.setSignedModifier(newmod);
}
OverflowModifier getOverflowModifier() const {
return operation.getOverflowModifier();
}
void setOverflowModifier(OverflowModifier newmod) {
operation.setOverflowModifier(newmod);
}
ShiftMaskModifier getShiftMaskModifier() const {
return operation.getShiftMaskModifier();
}
void setShiftMaskModifier(ShiftMaskModifier mod) {
operation.setShiftMaskModifier(mod);
}
StrictModifier getStrictModifier() const {
return operation.getStrictModifier();
}
void setStrictModifier(StrictModifier mod) {
operation.setStrictModifier(mod);
}
DefArgModifier getDefArgModifier() const {
return operation.getDefArgModifier();
}
void setDefArgModifier(DefArgModifier mod) {
operation.setDefArgModifier(mod);
}
StoreModifier getStoreModifier() const {
return operation.getStoreModifier();
}
void setStoreModifier(StoreModifier mod) {
operation.setStoreModifier(mod);
}
ExceptionModifier getExceptionModifier() const {
return operation.getExceptionModifier();
}
void setExceptionModifier(ExceptionModifier mod) {
operation.setExceptionModifier(mod);
}
AutoCompressModifier getAutoCompressModifier() const {
return operation.getAutoCompressModifier();
}
void setAutoCompressModifier(AutoCompressModifier mod) {
operation.setAutoCompressModifier(mod);
}
SpeculativeModifier getSpeculativeModifier() const {
return operation.getSpeculativeModifier();
}
void setSpeculativeModifier(SpeculativeModifier mod) {
operation.setSpeculativeModifier(mod);
}
ThrowModifier getThrowModifier() const {
return operation.getThrowModifier();
}
void setThrowModifier(ThrowModifier mod) {
operation.setThrowModifier(mod);
}
NewModifier1 getNewModifier1() const {
return operation.getNewModifier1();
}
void setNewModifier1(NewModifier1 mod) {
operation.setNewModifier1(mod);
}
NewModifier2 getNewModifier2() const {
return operation.getNewModifier2();
}
void setNewModifier2(NewModifier2 mod) {
operation.setNewModifier2(mod);
}
protected:
//
// Constructors
//
Inst(Opcode op, Modifier modifier, Type::Tag, Opnd* dst);
Inst(Opcode op, Modifier modifier, Type::Tag, Opnd* dst, Opnd* src);
Inst(Opcode op, Modifier modifier, Type::Tag, Opnd* dst, Opnd* src1, Opnd* src2);
Inst(Opcode op, Modifier modifier, Type::Tag, Opnd* dst, Opnd* src1, Opnd* src2, Opnd *src3);
Inst(Opcode op, Modifier modifier, Type::Tag, Opnd* dst, U_32 nSrcs);
//
// fields
//
Operation operation;
U_32 numSrcs;
Opnd* srcs[MAX_INST_SRCS];
Opnd* dst;
PersistentInstructionId pid;
U_32 id;
// called from CFG to detect BB->BB block edges
virtual Edge::Kind getEdgeKind(const Edge* edge) const;
virtual void removeRedundantBranch();
//
// protected accessor methods that deriving classes should override
//
virtual Opnd* getSrcExtended(U_32 srcIndex) const;
virtual void setSrcExtended(U_32 srcIndex, Opnd* src) {assert(0);}
virtual void handlePrintEscape(::std::ostream&, char code) const;
private:
friend class InstFactory;
void printFormatString(::std::ostream&, const char*) const;
};
class LabelInst : public Inst {
public:
U_32 getLabelId() const {return labelId;}
void setLabelId(U_32 id_) {labelId = id_;}
bool isLabel() const {return true;}
virtual bool isDispatchLabel() const {return false;}
virtual bool isCatchLabel() const {return false;}
void setState(void *stat) {state = stat;}
void * getState() {return state;}
void visit(InstFormatVisitor& visitor) {visitor.accept(this);}
virtual void printId(::std::ostream&) const;
protected:
LabelInst(U_32 id)
: Inst(Op_Label, Modifier(), Type::Void, OpndManager::getNullOpnd()),
labelId(id), state(NULL) {}
LabelInst(Opcode opc, U_32 id)
: Inst(opc, Modifier(), Type::Void, OpndManager::getNullOpnd()),
labelId(id), state(NULL) {}
virtual void handlePrintEscape(::std::ostream&, char code) const;
private:
friend class InstFactory;
U_32 labelId;
void* state;
};
class DispatchLabelInst: public LabelInst {
public:
bool isDispatchLabel() const {return true;}
void visit(InstFormatVisitor& visitor) {visitor.accept(this);}
void printId(::std::ostream&) const;
protected:
friend class InstFactory;
DispatchLabelInst(U_32 labelId) : LabelInst(labelId) {}
virtual void handlePrintEscape(::std::ostream&, char code) const;
};
class CatchLabelInst: public LabelInst {
public:
bool isCatchLabel() const {return true; }
void visit(InstFormatVisitor& visitor) {visitor.accept(this);}
U_32 getOrder() const {return order;}
Type* getExceptionType() const {return exception;}
void printId(::std::ostream&) const;
protected:
CatchLabelInst(U_32 id, U_32 ord, Type *except)
: LabelInst(id), order(ord), exception(except) {}
virtual void handlePrintEscape(::std::ostream&, char code) const;
private:
friend class InstFactory;
U_32 order;
Type *exception;
};
class MethodEntryInst : public LabelInst {
public:
MethodDesc* getMethodDesc() {return methodDesc;}
void visit(InstFormatVisitor& visitor) {visitor.accept(this);}
bool isMethodEntry() const { return true; }
protected:
MethodEntryInst(U_32 id, MethodDesc* md)
: LabelInst(Op_MethodEntry, id), methodDesc(md){}
virtual void handlePrintEscape(::std::ostream&, char code) const;
private:
friend class InstFactory;
MethodDesc* methodDesc;
};
class MethodMarkerInst : public Inst {
public:
void visit(InstFormatVisitor& visitor) {visitor.accept(this);}
bool isMethodMarker() const { return true; }
enum Kind {Entry, Exit};
bool isMethodEntryMarker() { return kind == Entry; }
bool isMethodExitMarker() { return kind == Exit; }
MethodDesc *getMethodDesc() { return methodDesc; }
void removeOpnd() {
setSrc(0, OpndManager::getNullOpnd());
if (numSrcs) numSrcs--;
}
protected:
virtual void handlePrintEscape(::std::ostream&, char code) const;
private:
friend class InstFactory;
MethodMarkerInst(Kind k, MethodDesc* md) :
Inst(k==Entry? Op_MethodEntry : Op_MethodEnd, Modifier(), Type::Void,
OpndManager::getNullOpnd()), kind(k), methodDesc(md), retOpnd(NULL) {}
MethodMarkerInst(Kind k, MethodDesc* md, Opnd *resOpnd) :
Inst(k==Entry? Op_MethodEntry : Op_MethodEnd, Modifier(), Type::Void,
OpndManager::getNullOpnd()), kind(k), methodDesc(md), retOpnd(resOpnd) {}
MethodMarkerInst(Kind k, MethodDesc* md, Opnd *obj, Opnd *resOpnd) :
Inst(k==Entry? Op_MethodEntry : Op_MethodEnd, Modifier(), Type::Void, OpndManager::getNullOpnd(),
obj), kind(k), methodDesc(md), retOpnd(resOpnd) {
assert(obj && !obj->isNull());
}
Kind kind;
MethodDesc* methodDesc;
Opnd* retOpnd;
};
//
// indicate exception information
//
class BranchInst : public Inst {
public:
bool isBranch() const {return true;}
void visit(InstFormatVisitor& visitor) {visitor.accept(this);}
void replaceTargetLabel(LabelInst* target) {targetLabel = target;}
LabelInst* getTargetLabel() const {return targetLabel;}
void swapTargets(LabelInst *target);
Edge *getTakenEdge(U_32 condition);
protected:
virtual void handlePrintEscape(::std::ostream&, char code) const;
virtual Edge::Kind getEdgeKind(const Edge* edge) const;
virtual void updateControlTransferInst(Node* oldTarget, Node* newTarget);
private:
friend class InstFactory;
BranchInst(Opcode op, LabelInst* target)
: Inst(op, Modifier(), Type::Void, OpndManager::getNullOpnd()), targetLabel(target) {};
BranchInst(Opcode op, Opnd* src, LabelInst* target)
: Inst(op, Modifier(), Type::Boolean, OpndManager::getNullOpnd(), src),
targetLabel(target) {}
BranchInst(Opcode op,
ComparisonModifier mod,
Type::Tag type,
Opnd* src,
LabelInst* target)
: Inst(op, mod, type, OpndManager::getNullOpnd(), src), targetLabel(target) {}
BranchInst(Opcode op,
ComparisonModifier mod,
Type::Tag type,
Opnd* src1,
Opnd* src2,
LabelInst* target)
: Inst(op, mod, type, OpndManager::getNullOpnd(), src1, src2), targetLabel(target) {}
LabelInst* targetLabel;
};
class SwitchInst : public Inst {
public:
LabelInst* getTarget(U_32 i) {
assert(i < numTargets);
return targetInsts[i];
}
LabelInst** getTargets() { return targetInsts; }
void visit(InstFormatVisitor& visitor) {visitor.accept(this);}
bool isSwitch() const {return true;}
LabelInst* getDefaultTarget() const {return defaultTargetInst;}
U_32 getNumTargets() {return numTargets;}
void replaceTargetLabel(U_32 i, LabelInst* target) {
assert(i < numTargets);
targetInsts[i] = target;
}
void replaceDefaultTargetLabel(LabelInst* target) { defaultTargetInst = target; }
protected:
virtual void handlePrintEscape(::std::ostream&, char code) const;
virtual Edge::Kind getEdgeKind(const Edge* edge) const;
virtual void updateControlTransferInst(Node* oldTarget, Node* newTarget);
private:
friend class InstFactory;
SwitchInst(Opnd* src, LabelInst** targets, U_32 nTargets, LabelInst* defTarget)
: Inst(Op_Switch, Modifier(), Type::Void, OpndManager::getNullOpnd(), src),
targetInsts(targets), defaultTargetInst(defTarget), numTargets(nTargets) {
}
LabelInst** targetInsts;
LabelInst* defaultTargetInst;
U_32 numTargets;
};
class ConstInst : public Inst {
public:
union ConstValue {
void* i; // I (can be NULL for ldnull)
I_32 i4; // I4
int64 i8; // I8
float s; // Single
double d; // Double
struct {
I_32 dword1;
I_32 dword2;
};
ConstValue() {dword1=dword2=0;}
};
void visit(InstFormatVisitor& visitor) {visitor.accept(this);}
virtual bool isConst() const {return true;}
ConstValue getValue() {return value;}
protected:
virtual void handlePrintEscape(::std::ostream&, char code) const;
private:
friend class InstFactory;
ConstInst(Opnd* d, ConstValue cv)
: Inst(Op_LdConstant, Modifier(), d->getType()->tag, d) { value = cv; }
ConstInst(Opnd* d, I_32 i4)
: Inst(Op_LdConstant, Modifier(), Type::Int32, d) {value.i4 = i4;}
ConstInst(Opnd* d, int64 i8)
: Inst(Op_LdConstant, Modifier(), Type::Int64, d) {value.i8 = i8;}
ConstInst(Opnd* d, float fs)
: Inst(Op_LdConstant, Modifier(), Type::Single, d) {value.s = fs;}
ConstInst(Opnd* d, double fd)
: Inst(Op_LdConstant, Modifier(), Type::Double, d) {value.d = fd;}
ConstInst(Opnd* d, void* ptr)
: Inst(Op_LdConstant, Modifier(), d->getType()->tag, d) {value.i = ptr;}
ConstInst(Opnd* d)
: Inst(Op_LdConstant, Modifier(), Type::NullObject, d) {value.i=NULL;}
ConstValue value;
};
class TokenInst : public Inst {
public:
void visit(InstFormatVisitor& visitor) {visitor.accept(this);}
U_32 getToken() const {return token;}
MethodDesc* getEnclosingMethod() {return enclosingMethod;}
bool isToken() const {return true;}
protected:
virtual void handlePrintEscape(::std::ostream&, char code) const;
private:
friend class InstFactory;
TokenInst(Opcode opc, Modifier mod, Type::Tag type, Opnd* d, U_32 t, MethodDesc* encMethod)
: Inst(opc, mod, type, d), token(t), enclosingMethod(encMethod) {}
U_32 token;
MethodDesc* enclosingMethod;
};
// for Throw_LinkingException
class LinkingExcInst : public Inst {
public:
void visit(InstFormatVisitor& visitor) {visitor.accept(this);}
Class_Handle getEnclosingClass() {return enclosingClass;}
U_32 getCPIndex() const {return cp_index;}
U_32 getOperation() const {return operation;}
private:
friend class InstFactory;
LinkingExcInst(Opcode opc, Modifier mod, Type::Tag type, Opnd* d,
Class_Handle encClass, U_32 cp_ndx, U_32 _operation)
: Inst(opc, mod, type, d),
enclosingClass(encClass), cp_index(cp_ndx), operation(_operation) {}
Class_Handle enclosingClass;
U_32 cp_index;
U_32 operation;
};
// for ldvar, ldvara & stvar instructions
class VarAccessInst : public Inst {
public:
void visit(InstFormatVisitor& visitor) {visitor.accept(this);}
bool isVarAccess() const {return true;}
VarOpnd* getVar() {
if (isStVar())
return (dst->isVarOpnd()) ? (VarOpnd*)dst : NULL;
else
return (getSrc(0)->isVarOpnd()) ? (VarOpnd*)getSrc(0) : NULL;
}
VarOpnd* getBaseVar() {
if (isStVar()) {
if (dst->isVarOpnd())
return dst->asVarOpnd();
else if (dst->isSsaVarOpnd())
return (dst->asSsaVarOpnd()->getVar());
else
return 0;
} else {
Opnd *src0 = getSrc(0);
if (src0->isVarOpnd())
return src0->asVarOpnd();
else if (src0->isSsaVarOpnd())
return (src0->asSsaVarOpnd()->getVar());
else
return 0;
}
}
VarAccessInst* getNextVarAccessInst() {return nextVarAccessInst;}
protected:
virtual void handlePrintEscape(::std::ostream&, char code) const;
private:
friend class InstFactory;
// ldvar & ldvara:
VarAccessInst(Opcode op, Type::Tag type, Opnd* dst, VarOpnd* var)
: Inst(op, Modifier(), type, dst, var) {
nextVarAccessInst = var->getVarAccessInsts();
var->addVarAccessInst(this);
}
// stvar:
VarAccessInst(Opcode op, Type::Tag type, VarOpnd* var, Opnd* src)
: Inst(op, Modifier(), type, var, src){
nextVarAccessInst = var->getVarAccessInsts();
var->addVarAccessInst(this);
}
// SsaVar forms
// ldvar & ldvara:
VarAccessInst(Opcode op, Type::Tag type, Opnd* dst, SsaVarOpnd* var)
: Inst(op, Modifier(), type, dst, var) {
VarOpnd *orgvar = var->getVar();
nextVarAccessInst = orgvar->getVarAccessInsts();
orgvar->addVarAccessInst(this);
}
// stvar:
VarAccessInst(Opcode op, Type::Tag type, SsaVarOpnd* var, Opnd* src)
: Inst(op, Modifier(), type, var, src){
VarOpnd *orgvar = var->getVar();
nextVarAccessInst = orgvar->getVarAccessInsts();
orgvar->addVarAccessInst(this);
}
VarAccessInst* nextVarAccessInst;
};
class MultiSrcInst : public Inst {
public:
void visit(InstFormatVisitor& visitor) {visitor.accept(this);}
bool isMultiSrcInst() const { return true; }
protected:
MultiSrcInst(Opcode op, Modifier mod, Type::Tag ty, Opnd* dst)
: Inst(op, mod, ty, dst), extendedSrcs(0), extendedSrcSpace(0) {}
MultiSrcInst(Opcode op, Modifier mod, Type::Tag ty, Opnd* dst, Opnd* src)
: Inst(op, mod, ty, dst, src), extendedSrcs(0), extendedSrcSpace(0) {}
MultiSrcInst(Opcode op, Modifier mod, Type::Tag ty, Opnd* dst, Opnd* src1, Opnd* src2)
: Inst(op, mod, ty, dst, src1, src2), extendedSrcs(0), extendedSrcSpace(0) {};
MultiSrcInst(Opcode op,
Modifier mod,
Type::Tag ty,
Opnd* dst,
U_32 nSrcs_,
Opnd** srcs_)
: Inst(op, mod, ty, dst, nSrcs_),
extendedSrcs(srcs_), extendedSrcSpace(nSrcs_)
{
switch (nSrcs_) {
default:
case 2: srcs[1] = srcs_[1];
case 1: srcs[0] = srcs_[0];
case 0: break;
}
for (U_32 i=2; i < nSrcs_; i++) {
srcs_[i-MAX_INST_SRCS] = srcs_[i];
srcs_[i] = 0;
}
}
private:
friend class InstFactory;
Opnd* getSrcExtended(U_32 srcIndex) const {
assert(srcIndex < (extendedSrcSpace + MAX_INST_SRCS));
return extendedSrcs[srcIndex - MAX_INST_SRCS];
}
void setSrcExtended(U_32 srcIndex, Opnd* src) {
assert(srcIndex < (extendedSrcSpace + MAX_INST_SRCS));
extendedSrcs[srcIndex - MAX_INST_SRCS] = src;
}
Opnd** extendedSrcs;
U_32 extendedSrcSpace;
void initSrcs(U_32 nSrcs_, Opnd**srcs_) {
switch (nSrcs_) {
default:
case 2: srcs[1] = srcs_[1];
case 1: srcs[0] = srcs_[0];
case 0: break;
}
for (U_32 i=2; i < nSrcs_; i++) {
srcs_[i-MAX_INST_SRCS] = srcs_[i];
extendedSrcs = srcs_ + MAX_INST_SRCS;
}
}
public:
void setNumSrcs(U_32 nSrcs) {
assert(nSrcs <= numSrcs);
numSrcs = nSrcs;
}
};
class TypeInst : public MultiSrcInst {
public:
Type* getTypeInfo() {return type;}
void visit(InstFormatVisitor& visitor) {visitor.accept(this);}
bool isType() const {return true; }
protected:
TypeInst(Opcode op, Modifier mod, Type::Tag ty, Opnd* dst, Type* td)
: MultiSrcInst(op, mod, ty, dst), type(td) {}
TypeInst(Opcode op, Modifier mod, Type::Tag ty, Opnd* dst,
Opnd* src, Type* td)
: MultiSrcInst(op, mod, ty, dst, src), type(td) {}
TypeInst(Opcode op, Modifier mod, Type::Tag ty, Opnd* dst,
Opnd* src1, Opnd* src2, Type* td)
: MultiSrcInst(op, mod, ty, dst, src1, src2), type(td) {}
TypeInst(Opcode op, Modifier mod, Type::Tag ty, Opnd* dst,
U_32 nArgs, Opnd** args_, Type* td)
: MultiSrcInst(op, mod, ty, dst, nArgs, args_), type(td){}
virtual void handlePrintEscape(::std::ostream&, char code) const;
private:
friend class InstFactory;
Type* type;
};
// for LoadField, LoadFieldAddr, LoadStatic, LoadStaticAddr, StoreStatic, StoreField
class FieldAccessInst : public MultiSrcInst {
public:
void visit(InstFormatVisitor& visitor) {visitor.accept(this);}
FieldDesc* getFieldDesc() {return fieldDesc;}
bool isFieldAccess() const {return true;}
protected:
virtual void handlePrintEscape(::std::ostream&, char code) const;
private:
friend class InstFactory;
FieldAccessInst(Opcode op,
Modifier mod,
Type::Tag type,
Opnd* dst,
FieldDesc* fd)
: MultiSrcInst(op, mod, type, dst), fieldDesc(fd) {}
FieldAccessInst(Opcode op,
Modifier mod,
Type::Tag type,
Opnd* dst,
Opnd* src,
FieldDesc* fd)
: MultiSrcInst(op, mod, type, dst, src), fieldDesc(fd) {}
FieldAccessInst(Opcode op,
Modifier mod,
Type::Tag type,
Opnd* dst,
Opnd* src1,
Opnd* src2,
FieldDesc* fd)
: MultiSrcInst(op, mod, type, dst, src1, src2), fieldDesc(fd) {}
FieldAccessInst(Opcode op,
Modifier mod,
Type::Tag type,
Opnd* dst,
U_32 numSrcs,
Opnd** srcs,
FieldDesc* fd)
: MultiSrcInst(op, mod, type, dst, numSrcs, srcs), fieldDesc(fd) {}
FieldDesc* fieldDesc;
};
class MethodInst : public MultiSrcInst {
public:
void visit(InstFormatVisitor& visitor) {visitor.accept(this);}
bool isMethod() const {return true;}
MethodDesc* getMethodDesc() {return methodDesc;}
void setMethodDesc(MethodDesc* desc) {methodDesc = desc;}
protected:
virtual void handlePrintEscape(::std::ostream&, char code) const;
friend class InstFactory;
MethodInst(Opcode op, Modifier mod, Type::Tag type, Opnd* dst, MethodDesc* md)
: MultiSrcInst(op, mod, type, dst), methodDesc(md) {}
MethodInst(Opcode op,
Modifier mod,
Type::Tag type,
Opnd* dst,
U_32 nArgs,
Opnd ** srcs,
MethodDesc* md)
: MultiSrcInst(op, mod, type, dst, nArgs, srcs), methodDesc(md) {}
MethodInst(Opcode op,
Modifier mod,
Type::Tag type,
Opnd* dst,
Opnd* base,
MethodDesc* md)
: MultiSrcInst(op, mod, type, dst, base), methodDesc(md) {}
MethodInst(Opcode op,
Modifier mod,
Type::Tag type,
Opnd* dst,
Opnd* base,
Opnd* extra,
MethodDesc* md)
: MultiSrcInst(op, mod, type, dst, base, extra), methodDesc(md) {}
private:
MethodDesc* methodDesc;
};
class MethodCallInst : public MethodInst {
public:
void visit(InstFormatVisitor& visitor) {visitor.accept(this);}
bool isMethodCall() const {return true;}
private:
friend class InstFactory;
MethodCallInst(Opcode op, Modifier mod,
Type::Tag type,
Opnd* dst,
U_32 nArgs,
Opnd** args_,
MethodDesc* md,
MemoryManager& mem_mgr)
: MethodInst(op, mod, type, dst, nArgs, args_, md){}
};
// for call instructions
class CallInst : public Inst {
public:
bool isCall() const {return true; }
void visit(InstFormatVisitor& visitor) {visitor.accept(this);}
Opnd* getFunPtr() {return srcs[0];}
U_32 getNumArgs() const {return getNumSrcOperands()-1;}
Opnd* getArg(U_32 argIndex) {return getSrc(argIndex+1);}
Opnd** getArgs() {args[0] = srcs[1]; return args;}
private:
friend class InstFactory;
CallInst(Opcode op, Modifier mod,
Type::Tag type,
Opnd* dst,
Opnd* ptr,
U_32 nArgs,
Opnd** args_,
MemoryManager& mem_mgr)
: Inst(op, mod, type, dst, nArgs+1)
{
args = args_;
switch (nArgs) {
default:
case 1: srcs[1] = args_[0];
case 0: srcs[0] = ptr;
}
}
Opnd* getSrcExtended(U_32 srcIndex) const {
assert(srcIndex != 1);
return args[srcIndex - 1];
}
void setSrcExtended(U_32 srcIndex, Opnd* src) {
assert(srcIndex != 1);
args[srcIndex - 1] = src;
}
Opnd** args;
};
// JIT helper calls
class JitHelperCallInst : public Inst {
public:
void visit(InstFormatVisitor& visitor) {visitor.accept(this);}
bool isJitHelperCallInst() const { return true; }
JitHelperCallId getJitHelperId() const {return jitHelperId;}
private:
virtual void handlePrintEscape(::std::ostream&, char code) const;
friend class InstFactory;
JitHelperCallInst(Opcode op,
Modifier mod,
Type::Tag type,
Opnd* dst,
U_32 nArgs,
Opnd** args_,
JitHelperCallId id) : Inst(op, mod, type, dst, nArgs),
jitHelperId(id) {
args = NULL;
switch (nArgs) {
default: args = args_ + MAX_INST_SRCS;
case 2: srcs[1] = args_[1];
case 1: srcs[0] = args_[0];
case 0: break;
}
}
Opnd* getSrcExtended(U_32 srcIndex) const {
return args[srcIndex - MAX_INST_SRCS];
}
void setSrcExtended(U_32 srcIndex, Opnd* src) {
args[srcIndex - MAX_INST_SRCS] = src;
}
Opnd** args;
JitHelperCallId jitHelperId;
};
// VM helper calls
class VMHelperCallInst : public Inst {
public:
void visit(InstFormatVisitor& visitor) {visitor.accept(this);}
bool isVMHelperCallInst() const { return true; }
VM_RT_SUPPORT getVMHelperId() const {return vmHelperId;}
bool isThrowLazy() const {return vmHelperId == VM_RT_THROW_LAZY;}
private:
virtual void handlePrintEscape(::std::ostream&, char code) const;
friend class InstFactory;
VMHelperCallInst(Opcode op,
Modifier mod,
Type::Tag type,
Opnd* dst,
U_32 nArgs,
Opnd** args_,
VM_RT_SUPPORT id)
: Inst(op, mod, type, dst, nArgs), vmHelperId(id)
{
args = args_;
switch (nArgs) {
default:
case 2: srcs[1] = args_[1];
case 1: srcs[0] = args_[0];
case 0: break;
}
}
Opnd* getSrcExtended(U_32 srcIndex) const {
return args[srcIndex];
}
void setSrcExtended(U_32 srcIndex, Opnd* src) {
args[srcIndex] = src;
}
Opnd** args;
VM_RT_SUPPORT vmHelperId;
};
// phi instructions
class PhiInst : public MultiSrcInst {
public:
void visit(InstFormatVisitor& visitor) {visitor.accept(this);}
bool isMultiSrcInst() const { return false; }
bool isPhi() const { return true; }
private:
friend class InstFactory;
PhiInst(Type::Tag type, Opnd* dst, U_32 nArgs, Opnd** args_ )
: MultiSrcInst(Op_Phi, Modifier(), type, dst, nArgs, args_)
{
}
bool isHeaderCriticalInst() const {return true;}
};
// pi instructions
class TauPiInst : public Inst {
public:
void visit(InstFormatVisitor& visitor) { visitor.accept(this);}
bool isTauPi() const { return true; }
const PiCondition *getCond() const { return cond; };
protected:
virtual void handlePrintEscape(::std::ostream&, char code) const;
private:
friend class InstFactory;
friend class InsertPi; // needs to update the cond below;
TauPiInst(Type::Tag type, Opnd* dst, Opnd* src, Opnd *tau, PiCondition *cond0)
: Inst(Op_TauPi, Modifier(), type, dst, src, tau),
cond(cond0)
{
}
PiCondition *cond;
};
class InstFactory {
public:
MemoryManager& getMemManager() {return memManager;}
Inst* clone(Inst* inst, OpndManager& opndManager, OpndRenameTable *table);
// Numeric compute
Inst* makeAdd(Modifier mod, Opnd* dst, Opnd* src1, Opnd* src2);
Inst* makeSub(Modifier mod, Opnd* dst, Opnd* src1, Opnd* src2);
Inst* makeMul(Modifier mod, Opnd* dst, Opnd* src1, Opnd* src2);
Inst* makeTauDiv(Modifier mod, Opnd* dst, Opnd* src1, Opnd* src2, Opnd *tauCheckedOpnds);
Inst* makeTauRem(Modifier mod, Opnd* dst, Opnd* src1, Opnd* src2, Opnd *tauCheckedOpnds);
Inst* makeNeg(Opnd* dst, Opnd* src);
Inst* makeMulHi(Modifier mod, Opnd* dst, Opnd* src1, Opnd* src2);
Inst* makeMin(Opnd* dst, Opnd* src1, Opnd* src2);
Inst* makeMax(Opnd* dst, Opnd* src1, Opnd* src2);
Inst* makeAbs(Opnd* dst, Opnd* src1);
// Bitwise
Inst* makeAnd(Opnd* dst, Opnd* src1, Opnd* src2);
Inst* makeOr(Opnd* dst, Opnd* src1, Opnd* src2);
Inst* makeXor(Opnd* dst, Opnd* src1, Opnd* src2);
Inst* makeNot(Opnd* dst, Opnd* src);
// Selection
Inst* makeSelect(Opnd* dst, Opnd* src1, Opnd* src2, Opnd* src3);
// conversion
Inst* makeConv(Modifier mod, Type::Tag toType, Opnd* dst, Opnd* src);
Inst* makeConvZE(Modifier mod, Type::Tag toType, Opnd* dst, Opnd* src);
Inst* makeConvUnmanaged(Modifier mod, Type::Tag toType, Opnd* dst, Opnd* src);
// shifts
Inst* makeShladd(Opnd* dst, Opnd* value, Opnd* shiftAmount, Opnd *addTo); // shiftAmount must be constant
Inst* makeShl(Modifier mod, Opnd* dst, Opnd* value, Opnd* shiftAmount);
Inst* makeShr(Modifier mod1, Opnd* dst, Opnd* value, Opnd* shiftAmount);
// comparison
Inst* makeCmp(ComparisonModifier mod, Type::Tag type, Opnd* dst, Opnd* src1, Opnd* src2);
Inst* makeCmp3(ComparisonModifier mod, Type::Tag type, Opnd* dst, Opnd* src1, Opnd* src2);
// Control flow
Inst* makeBranch(ComparisonModifier mod, Type::Tag, Opnd* src1, Opnd* src2, LabelInst* labelInst);
Inst* makeBranch(ComparisonModifier mod, Type::Tag, Opnd* src, LabelInst* labelInst);
Inst* makeJump(LabelInst* labelInst);
Inst* makeSwitch(Opnd* src, U_32 nLabels, LabelInst** labelInsts, LabelInst* defaultLabel);
Inst* makeDirectCall(Opnd* dst,
Opnd* tauNullChecked, Opnd* tauTypesChecked,
U_32 numArgs, Opnd** args,
MethodDesc*);
Inst* makeTauVirtualCall(Opnd* dst,
Opnd* tauNullChecked, Opnd *tauTypesChecked,
U_32 numArgs, Opnd** args,
MethodDesc*);
Inst* makeIndirectCall(Opnd* dst, Opnd* funPtr,
Opnd* tauNullCheckedFirstArg, Opnd *tauTypesChecked,
U_32 numArgs, Opnd** args);
Inst* makeIndirectMemoryCall(Opnd* dst, Opnd* funPtr,
Opnd *tauNullCheckedFirstArg,
Opnd *tauTypesChecked,
U_32 numArgs, Opnd** args);
Inst* makeJitHelperCall(Opnd* dst, JitHelperCallId id,
Opnd* tauNullChecked, Opnd* tauTypesChecked,
U_32 numArgs, Opnd** args);
Inst* makeVMHelperCall(Opnd* dst, VM_RT_SUPPORT id, U_32 numArgs,
Opnd** args);
Inst* makeIdentHC(Opnd* dst, Opnd* src);
Inst* makeReturn(Opnd* src);
Inst* makeReturn(); // void return type
Inst* makeCatch(Opnd* dst);
Inst* makeCatchLabel(U_32 labelId, U_32 exceptionOrder, Type* exceptionType);
CatchLabelInst* makeCatchLabel(U_32 exceptionOrder, Type* exceptionType);
Inst* makeThrow(ThrowModifier mod, Opnd* exceptionObj);
Inst* makePseudoThrow();
Inst* makeThrowSystemException(CompilationInterface::SystemExceptionId exceptionId);
Inst* makeThrowLinkingException(Class_Handle encClass, U_32 CPIndex, U_32 operation);
Inst* makeLeave(LabelInst* labelInst);
Inst* makeJSR(LabelInst* labelInst);
Inst* makeRet(Opnd *src); // JSR-RET pair
Inst* makeSaveRet(Opnd *dst); // JSR-RET pair
// load, store, & mov
Inst* makeCopy(Opnd* dst, Opnd* src);
Inst* makeDefArg(Modifier, Opnd* arg);
Inst* makeLdConst(Opnd* dst, I_32 val);
Inst* makeLdConst(Opnd* dst, int64 val);
Inst* makeLdConst(Opnd* dst, float val);
Inst* makeLdConst(Opnd* dst, double val);
Inst* makeLdConst(Opnd* dst, ConstInst::ConstValue val);
Inst* makeLdNull(Opnd* dst);
Inst* makeLdRef(Modifier mod, Opnd* dst, MethodDesc* enclosingMethod, U_32 token);
Inst* makeLdVar(Opnd* dst, VarOpnd* var);
Inst* makeLdVar(Opnd* dst, SsaVarOpnd* var);
Inst* makeLdVarAddr(Opnd* dst, VarOpnd* var);
Inst* makeTauLdInd(Modifier, Type::Tag type, Opnd* dst, Opnd* ptr,
Opnd *tauNonNullBase, Opnd *tauAddressInRange);
Inst* makeTauLdField(Modifier, Type* type, Opnd* dst, Opnd* base,
Opnd *tauNonNullBase, Opnd *tauObjectTypeChecked,
FieldDesc*);
Inst* makeLdStatic(Modifier, Type* type, Opnd* dst, FieldDesc*);
Inst* makeTauLdElem(Modifier, Type* type, Opnd* dst, Opnd* array, Opnd* index,
Opnd *tauNonNullBase, Opnd *tauAddressInRange);
Inst* makeLdFieldAddr(Opnd* dst, Opnd* base, FieldDesc*);
Inst* makeLdStaticAddr(Opnd* dst, FieldDesc*);
Inst* makeLdElemAddr(Type* type, Opnd* dst, Opnd* array, Opnd* index);
Inst* makeTauLdVTableAddr(Opnd* dst, Opnd* base, Opnd *tauBaseNonNull);
Inst* makeTauLdIntfcVTableAddr(Opnd* dst, Opnd* base, Type* vtableType);
Inst* makeTauLdVirtFunAddr(Opnd* dst, Opnd* vtable,
Opnd *tauVtableHasDesc,
MethodDesc*);
Inst* makeTauLdVirtFunAddrSlot(Opnd* dst, Opnd* vtable,
Opnd *tauVtableHasDesc, MethodDesc*);
Inst* makeLdFunAddr(Opnd* dst, MethodDesc*);
Inst* makeLdFunAddrSlot(Opnd* dst, MethodDesc*);
Inst* makeGetVTableAddr(Opnd* dst, ObjectType *type);
Inst* makeGetClassObj(Opnd* dst, ObjectType *type);
Inst* makeTauArrayLen(Opnd* dst, Type::Tag type, Opnd* base, Opnd *tauBaseNonNull,
Opnd *tauBaseIsArray);
Inst* makeLdArrayBaseAddr(Type* type, Opnd* dst, Opnd* array);
Inst* makeAddScaledIndex(Opnd* dst, Opnd* base, Opnd* index);
Inst* makeStVar(VarOpnd* var, Opnd* src);
Inst* makeStVar(SsaVarOpnd* var, Opnd* src);
Inst* makeTauStInd(Modifier, Type::Tag, Opnd* src, Opnd* ptr, Opnd *tauNonNullBase,
Opnd *tauAddressInRange, Opnd *tauElemTypeChecked);
Inst* makeTauStField(Modifier, Type::Tag type, Opnd* src, Opnd* base,
Opnd *tauNonNullBase, Opnd *tauObjectHasField,
Opnd *tauFieldTypeChecked,
FieldDesc*);
Inst* makeTauStElem(Modifier, Type::Tag, Opnd* src, Opnd* array, Opnd* index,
Opnd *tauNonNullBase, Opnd *tauAddressInRange,
Opnd *tauElemTypeChecked);
Inst* makeTauStStatic(Modifier, Type::Tag type, Opnd* src,
Opnd *tauFieldTypeChecked, FieldDesc*);
Inst* makeTauStRef(Modifier, Type::Tag, Opnd* src, Opnd* pointer, Opnd* objectbase,
Opnd *tauNonNullBase, Opnd *tauAddressInRange, Opnd *tauElemTypeChecked);
// checks
Inst* makeTauCheckBounds(Opnd *dst, Opnd* arrayLen, Opnd* index);
Inst* makeTauCheckLowerBound(Opnd *dst, Opnd* lb, Opnd* idx); // tests (lb <= idx);
Inst* makeTauCheckUpperBound(Opnd *dst, Opnd* idx, Opnd* ub); // tests (idx < ub);
Inst* makeTauCheckNull(Opnd* dst, Opnd* base);
Inst* makeTauCheckZero(Opnd* dst, Opnd* src);
Inst* makeTauCheckDivOpnds(Opnd* dst, Opnd* src1, Opnd* src2);
Inst* makeTauCheckElemType(Opnd* dst, Opnd* array, Opnd* src, Opnd *tauNullChecked,
Opnd *tauIsArray);
Inst* makeTauCheckFinite(Opnd* dst, Opnd* src);
// alloc
Inst* makeNewObj(Opnd* dst, Type* type);
Inst* makeNewArray(Opnd* dst, Opnd* numElems, Type* elemType);
Inst* makeNewMultiArray(Opnd* dst, U_32 dimensions, Opnd** numElems, Type* elemType);
// sync
Inst* makeTauMonitorEnter(Opnd* src, Opnd *tauSrcNonNull);
Inst* makeTauMonitorExit(Opnd* src, Opnd *tauSrcNonNull);
Inst* makeTypeMonitorEnter(Type *type);
Inst* makeTypeMonitorExit(Type *type);
// lowered parts of monitor enter/exit
Inst* makeLdLockAddr(Opnd *dst, Opnd *obj); // result is ref:int16
Inst* makeIncRecCount(Opnd *obj, Opnd *oldValue);
Inst* makeTauBalancedMonitorEnter(Opnd* dst, Opnd *src, Opnd *lockAddr,
Opnd *tauSrcNonNull); // result is I_32
Inst* makeBalancedMonitorExit(Opnd* src, Opnd *lockAddr, Opnd *enterDst);
Inst* makeTauOptimisticBalancedMonitorEnter(Opnd* dst, Opnd *src, Opnd *lockAddr,
Opnd *tauSrcNonNull); // result is I_32
Inst* makeOptimisticBalancedMonitorExit(Opnd* src, Opnd *lockAddr, Opnd *enterDst);
Inst* makeMonitorEnterFence(Opnd* src); // elided MonitorEnter, just enforce memory model
Inst* makeMonitorExitFence(Opnd* src); // elided MonitorExit, just enforce memory model
// type checking
Inst* makeTauStaticCast(Opnd* dst, Opnd* src, Opnd *tauCastChecked,
Type* type);
Inst* makeTauCast(Opnd* dst, Opnd* src, Opnd *tauNullChecked, Type* type);
Inst* makeTauAsType(Opnd* dst, Opnd* src, Opnd *tauNullChecked, Type* type);
Inst* makeTauInstanceOf(Opnd* dst, Opnd* src, Opnd *tauCheckedNull, Type* type);
Inst* makeInitType(Type* type);
// labels
LabelInst* makeLabel();
// method entry/exit
LabelInst* makeMethodEntryLabel(MethodDesc* methodDesc);
Inst* makeMethodMarker(MethodMarkerInst::Kind kind, MethodDesc* methodDesc,
Opnd *obj, Opnd *retOpnd);
Inst* makeMethodMarker(MethodMarkerInst::Kind kind, MethodDesc* methodDesc, Opnd *retOpnd);
Inst* makeMethodMarker(MethodMarkerInst::Kind kind, MethodDesc* methodDesc);
// SSA
Inst* makePhi(Opnd* dst, U_32 numOpnds, Opnd** opnds); // array is copied
Inst* makeTauPi(Opnd* dst, Opnd* src, Opnd *tau, PiCondition *cond);
// profile counter increment
Inst* makeIncCounter(U_32 val);
Inst* makePrefetch(Opnd* addr); // prefetch
// compressed references
Inst* makeUncompressRef(Opnd* dst, Opnd* compref);
Inst* makeCompressRef(Opnd* dst, Opnd* uncompref);
Inst* makeLdFieldOffset(Opnd* dst, FieldDesc *fieldDesc);
Inst* makeLdFieldOffsetPlusHeapbase(Opnd* dst, FieldDesc *fieldDesc);
Inst* makeLdArrayBaseOffset(Opnd* dst, Type *elemType);
Inst* makeLdArrayBaseOffsetPlusHeapbase(Opnd* dst, Type *elemType);
Inst* makeLdArrayLenOffset(Opnd* dst, Type *elemType);
Inst* makeLdArrayLenOffsetPlusHeapbase(Opnd* dst, Type *elemType);
Inst* makeAddOffset(Opnd* dst, Opnd* ref, Opnd* offset);
Inst* makeAddOffsetPlusHeapbase(Opnd* dst, Opnd* ref, Opnd* offset);
// new tau methods
Inst* makeTauPoint(Opnd *dst);
Inst* makeTauEdge(Opnd *dst);
Inst* makeTauAnd(Opnd *dst, U_32 numOpnds, Opnd** opnds); // array is copied
Inst* makeTauUnsafe(Opnd *dst);
Inst* makeTauSafe(Opnd *dst);
Inst* makeTauCheckCast(Opnd *taudst, Opnd* src, Opnd* tauCheckedNull, Type* type);
Inst* makeTauHasType(Opnd *taudst, Opnd* src, Type* type);
Inst* makeTauHasExactType(Opnd *taudst, Opnd* src, Type* type);
Inst* makeTauIsNonNull(Opnd *taudst, Opnd* src);
//
//
//
U_32 createLabelNumber() {return maxNumLabels++; }
U_32 getMaxNumLabels() {return maxNumLabels; }
U_32 getNumInsts() {return numInsts; }
private:
U_32 maxNumLabels; // number of labels generated
U_32 numInsts; // number of instructions generated
MemoryManager& memManager;
//
// Private constructor
//
// We only allow IRManager to create an InstFactory.
//
friend class IRManager;
InstFactory(MemoryManager& mm, MethodDesc & md);
//
// private helpers for making different types of instructions
//
Opnd** copyOpnds(Opnd** srcs, U_32 numSrcs);
Opnd** copyOpnds(Opnd* src1, Opnd** srcs, U_32 numSrcs);
Opnd** copyOpnds(Opnd* src1, Opnd* src2, Opnd** srcs, U_32 numSrcs);
//
// methods for copying instructions
//
friend class CloneVisitor;
Inst* makeClone(Inst*, OpndManager&, OpndRenameTable&);
LabelInst* makeClone(LabelInst*, OpndManager&, OpndRenameTable&);
DispatchLabelInst* makeClone(DispatchLabelInst*, OpndManager&, OpndRenameTable&);
CatchLabelInst* makeClone(CatchLabelInst*, OpndManager&, OpndRenameTable&);
MethodEntryInst* makeClone(MethodEntryInst*, OpndManager&, OpndRenameTable&);
MethodMarkerInst* makeClone(MethodMarkerInst*, OpndManager&, OpndRenameTable&);
BranchInst* makeClone(BranchInst*, OpndManager&, OpndRenameTable&);
SwitchInst* makeClone(SwitchInst*, OpndManager&, OpndRenameTable&);
ConstInst* makeClone(ConstInst*, OpndManager&, OpndRenameTable&);
TokenInst* makeClone(TokenInst*, OpndManager&, OpndRenameTable&);
LinkingExcInst* makeClone(LinkingExcInst*, OpndManager&, OpndRenameTable&);
VarAccessInst* makeClone(VarAccessInst*, OpndManager&, OpndRenameTable&);
TypeInst* makeClone(TypeInst*, OpndManager&, OpndRenameTable&);
FieldAccessInst* makeClone(FieldAccessInst*, OpndManager&, OpndRenameTable&);
MethodInst* makeClone(MethodInst*, OpndManager&, OpndRenameTable&);
MethodCallInst* makeClone(MethodCallInst*, OpndManager&, OpndRenameTable&);
CallInst* makeClone(CallInst*, OpndManager&, OpndRenameTable&);
JitHelperCallInst* makeClone(JitHelperCallInst*, OpndManager&, OpndRenameTable&);
VMHelperCallInst* makeClone(VMHelperCallInst*, OpndManager&, OpndRenameTable&);
PhiInst* makeClone(PhiInst*, OpndManager&, OpndRenameTable&);
MultiSrcInst* makeClone(MultiSrcInst*, OpndManager&, OpndRenameTable&);
public:
Inst* makeInst(Opcode op, Modifier mod, Type::Tag, Opnd* dst);
Inst* makeInst(Opcode op, Modifier mod, Type::Tag, Opnd* dst, Opnd* src);
Inst* makeInst(Opcode op,
Modifier mod,
Type::Tag,
Opnd* dst,
Opnd* src1,
Opnd* src2);
// add a new source at end of sources
void appendSrc(MultiSrcInst*, Opnd *newSrc);
private:
// makes a copy of a LabelInst
LabelInst* makeLabelInst(U_32 labelId);
LabelInst* makeLabelInst(Opcode opc, U_32 labelId);
DispatchLabelInst* makeDispatchLabelInst(U_32 labelId);
CatchLabelInst* makeCatchLabelInst(U_32 lableId,
U_32 ord,
Type *exceptionType);
MethodEntryInst* makeMethodEntryInst(U_32 labelId, MethodDesc*) ;
MethodMarkerInst* makeMethodMarkerInst(MethodMarkerInst::Kind, MethodDesc*,
Opnd *obj, Opnd *retOpnd);
MethodMarkerInst* makeMethodMarkerInst(MethodMarkerInst::Kind, MethodDesc*, Opnd *retOpnd);
MethodMarkerInst* makeMethodMarkerInst(MethodMarkerInst::Kind, MethodDesc*);
BranchInst* makeBranchInst(Opcode, LabelInst* target);
BranchInst* makeBranchInst(Opcode, Opnd *src, LabelInst* target);
BranchInst* makeBranchInst(Opcode, ComparisonModifier mod,
Type::Tag, Opnd* src, LabelInst* target);
BranchInst* makeBranchInst(Opcode,
ComparisonModifier mod,
Type::Tag,
Opnd* src1,
Opnd* src2,
LabelInst* target);
SwitchInst* makeSwitchInst(Opnd* src,
LabelInst** targets,
U_32 nTargets,
LabelInst* defTarget);
ConstInst* makeConstInst(Opnd* dst, I_32 i4);
ConstInst* makeConstInst(Opnd* dst, int64 i8) ;
ConstInst* makeConstInst(Opnd* dst, float fs);
ConstInst* makeConstInst(Opnd* dst, double fd) ;
ConstInst* makeConstInst(Opnd* dst, ConstInst::ConstValue cv);
ConstInst* makeConstInst(Opnd* dst);
//
// fix parameter names!
//
TokenInst* makeTokenInst(Opcode opc, Modifier mod, Type::Tag, Opnd* dst, U_32 t, MethodDesc* encMethod);
LinkingExcInst* makeLinkingExcInst(Opcode opc, Modifier mod, Type::Tag type, Opnd* dst,
Class_Handle encClass, U_32 CPIndex, U_32 operation);
VarAccessInst* makeVarAccessInst(Opcode, Type::Tag, Opnd* dst, VarOpnd* var);
VarAccessInst* makeVarAccessInst(Opcode, Type::Tag, VarOpnd* var, Opnd* src);
VarAccessInst* makeVarAccessInst(Opcode, Type::Tag, Opnd* dst,
SsaVarOpnd* var);
VarAccessInst* makeVarAccessInst(Opcode, Type::Tag, SsaVarOpnd* var,
Opnd* src);
TypeInst* makeTypeInst(Opcode, Modifier mod, Type::Tag, Opnd* dst, Type*);
TypeInst* makeTypeInst(Opcode, Modifier mod, Type::Tag, Opnd* dst, Opnd* src, Type*);
TypeInst* makeTypeInst(Opcode,
Modifier mod,
Type::Tag,
Opnd* dst,
Opnd* src1,
Opnd* src2,
Type* td);
TypeInst* makeTypeInst(Opcode,
Modifier mod,
Type::Tag,
Opnd* dst,
Opnd* src1,
Opnd* src2,
Opnd* src3,
Type* td);
TypeInst* makeTypeInst(Opcode,
Modifier mod,
Type::Tag,
Opnd* dst,
Opnd* src1,
Opnd* src2,
Opnd* src3,
Opnd* src4,
Type* td);
TypeInst* makeTypeInst(Opcode,
Modifier mod,
Type::Tag,
Opnd* dst,
U_32 nArgs,
Opnd** args,
Type*);
FieldAccessInst* makeFieldAccessInst(Opcode, Modifier mod, Type::Tag, Opnd* dst, FieldDesc*);
FieldAccessInst* makeFieldAccessInst(Opcode, Modifier mod, Type::Tag, Opnd* dst, Opnd* src, FieldDesc*);
FieldAccessInst* makeFieldAccessInst(Opcode,
Modifier mod,
Type::Tag type,
Opnd* dst,
Opnd* src1,
Opnd* src2,
FieldDesc* fd);
FieldAccessInst* makeFieldAccessInst(Opcode,
Modifier mod,
Type::Tag type,
Opnd* dst,
U_32 nSrcs,
Opnd** srcs,
FieldDesc* fd);
MethodInst* makeMethodInst(Opcode, Modifier mod, Type::Tag type, Opnd* dst, MethodDesc* md);
MethodInst* makeMethodInst(Opcode,
Modifier mod,
Type::Tag,
Opnd* dst,
U_32 nArgs,
MethodDesc*);
MethodInst* makeMethodInst(Opcode,
Modifier mod,
Type::Tag type,
Opnd* dst,
Opnd* base,
MethodDesc*);
MethodInst* makeMethodInst(Opcode,
Modifier mod,
Type::Tag type,
Opnd* dst,
Opnd* base,
Opnd* tauVtableHasMethod,
MethodDesc*);
MethodInst* makeMethodInst(Opcode,
Modifier mod,
Type::Tag,
Opnd* dst,
U_32 nArgs,
Opnd** args_,
MethodDesc*);
MethodCallInst* makeMethodCallInst(Opcode,
Modifier mod,
Type::Tag,
Opnd* dst,
U_32 nArgs,
Opnd** args_,
MethodDesc*);
CallInst* makeCallInst(Opcode op, Modifier mod,
Type::Tag,
Opnd* dst,
Opnd* ptr,
U_32 nArgs,
Opnd** args);
JitHelperCallInst* makeJitHelperCallInst(Opcode op,
Modifier mod,
Type::Tag,
Opnd* dst,
U_32 nArgs,
Opnd** args_,
JitHelperCallId id);
VMHelperCallInst* makeVMHelperCallInst(Opcode op,
Modifier mod,
Type::Tag,
Opnd* dst,
U_32 nArgs,
Opnd** args_,
VM_RT_SUPPORT id);
PhiInst* makePhiInst(Type::Tag type, Opnd* dst, U_32 nArgs, Opnd** args_);
MultiSrcInst* makeMultiSrcInst(Opcode, Modifier mod, Type::Tag, Opnd* dst);
MultiSrcInst* makeMultiSrcInst(Opcode, Modifier mod, Type::Tag, Opnd* dst, Opnd* src);
MultiSrcInst* makeMultiSrcInst(Opcode, Modifier mod, Type::Tag, Opnd* dst, Opnd* src1, Opnd* src2);
MultiSrcInst* makeMultiSrcInst(Opcode, Modifier mod, Type::Tag, Opnd* dst, Opnd* src1, Opnd* src2, Opnd* src3);
MultiSrcInst* makeMultiSrcInst(Opcode, Modifier mod, Type::Tag, Opnd* dst, Opnd* src1, Opnd* src2, Opnd* src3, Opnd* src4);
MultiSrcInst* makeMultiSrcInst(Opcode, Modifier mod, Type::Tag, Opnd* dst, U_32 nSrcs, Opnd** srcs);
};
//
// Basic container class for instructions
//
class InstDeque : StlDeque<Inst*> {
public:
InstDeque(MemoryManager& mm) : StlDeque<Inst*>(mm) {}
bool isEmpty() const {return empty();}
Inst* popFront() {Inst* inst=front();pop_front();return inst;}
Inst* popBack() {Inst* inst=back();pop_back();return inst;}
void pushFront(Inst* inst) {push_front(inst);}
void pushBack(Inst* inst) {push_back(inst);}
};
class InstOptimizer {
public:
virtual ~InstOptimizer() {}
// returns 0 or an optimized version of inst;
virtual Inst*
optimizeInst(Inst* inst) {
return dispatch(inst);
}
// Numeric compute
virtual Inst*
caseAdd(Inst* inst)=0; // {return caseDefault(inst);}
virtual Inst*
caseMul(Inst* inst)=0; // {return caseDefault(inst);}
virtual Inst*
caseSub(Inst* inst)=0; // {return caseDefault(inst);}
virtual Inst*
caseTauDiv(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauRem(Inst* inst)=0; // {return caseDefault(inst);}
virtual Inst*
caseNeg(Inst* inst)=0; // {return caseDefault(inst);}
virtual Inst*
caseMulHi(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseMin(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseMax(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseAbs(Inst* inst)=0;// {return caseDefault(inst);}
// Bitwise
virtual Inst*
caseAnd(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseOr(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseXor(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseNot(Inst* inst)=0;// {return caseDefault(inst);}
// selection
virtual Inst*
caseSelect(Inst* inst)=0;// {return caseDefault(inst);}
// conversion
virtual Inst*
caseConv(Inst* inst)=0;// {return caseDefault(inst);}
// conversion
virtual Inst*
caseConvZE(Inst* inst)=0;// {return caseDefault(inst);}
// conversion
virtual Inst*
caseConvUnmanaged(Inst* inst)=0;// {return caseDefault(inst);}
// shifts
virtual Inst*
caseShladd(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseShl(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseShr(Inst* inst)=0;// {return caseDefault(inst);}
// comparison
virtual Inst*
caseCmp(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseCmp3(Inst* inst)=0;// {return caseDefault(inst);}
// Control flow
virtual Inst*
caseBranch(BranchInst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseJump(BranchInst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseSwitch(SwitchInst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseDirectCall(MethodCallInst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauVirtualCall(MethodCallInst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseIndirectCall(CallInst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseIndirectMemoryCall(CallInst* inst)=0;//{return caseDefault(inst);}
virtual Inst*
caseJitHelperCall(JitHelperCallInst* inst)=0;//{return caseDefault(inst);}
virtual Inst*
caseVMHelperCall(VMHelperCallInst* inst)=0;//{return caseDefault(inst);}
virtual Inst*
caseReturn(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseCatch(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseThrow(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
casePseudoThrow(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseThrowSystemException(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseThrowLinkingException(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseLeave(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseJSR(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseRet(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseSaveRet(Inst* inst)=0;// {return caseDefault(inst);}
// load, store & mov
virtual Inst*
caseCopy(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseDefArg(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseLdConstant(ConstInst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseLdNull(ConstInst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseLdRef(TokenInst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseLdVar(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseLdVarAddr(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauLdInd(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauLdField(FieldAccessInst* inst)=0;//{return caseDefault(inst);}
virtual Inst*
caseLdStatic(FieldAccessInst* inst)=0;//{return caseDefault(inst);}
virtual Inst*
caseTauLdElem(TypeInst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseLdFieldAddr(FieldAccessInst* inst)=0;//{return caseDefault(inst);}
virtual Inst*
caseLdStaticAddr(FieldAccessInst* inst)=0;//{return caseDefault(inst);}
virtual Inst*
caseLdElemAddr(TypeInst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauLdVTableAddr(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauLdIntfcVTableAddr(TypeInst* inst)=0;//{return caseDefault(inst);}
virtual Inst*
caseTauLdVirtFunAddr(MethodInst* inst)=0;//{return caseDefault(inst);}
virtual Inst*
caseTauLdVirtFunAddrSlot(MethodInst* inst)=0;//{return caseDefault(inst);}
virtual Inst*
caseLdFunAddr(MethodInst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseLdFunAddrSlot(MethodInst* inst)=0;//{return caseDefault(inst);}
virtual Inst*
caseGetVTableAddr(TypeInst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseGetClassObj(TypeInst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauArrayLen(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseLdArrayBaseAddr(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseAddScaledIndex(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseStVar(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauStInd(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauStField(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauStElem(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauStStatic(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauStRef(Inst* inst)=0;// {return caseDefault(inst);}
// checks
virtual Inst*
caseTauCheckBounds(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauCheckLowerBound(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauCheckUpperBound(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauCheckNull(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauCheckZero(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauCheckDivOpnds(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauCheckElemType(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauCheckFinite(Inst* inst)=0;// {return caseDefault(inst);}
// alloc
virtual Inst*
caseNewObj(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseNewArray(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseNewMultiArray(Inst* inst)=0;// {return caseDefault(inst);}
// sync
virtual Inst*
caseTauMonitorEnter(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauMonitorExit(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTypeMonitorEnter(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTypeMonitorExit(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseLdLockAddr(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseIncRecCount(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauBalancedMonitorEnter(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseBalancedMonitorExit(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauOptimisticBalancedMonitorEnter(Inst* inst)=0;//{return caseDefault(inst);}
virtual Inst*
caseOptimisticBalancedMonitorExit(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseMonitorEnterFence(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseMonitorExitFence(Inst* inst)=0;// {return caseDefault(inst);}
// type checking
virtual Inst*
caseTauStaticCast(TypeInst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauCast(TypeInst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseSizeof(TypeInst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauAsType(TypeInst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauInstanceOf(TypeInst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseInitType(TypeInst* inst)=0;// {return caseDefault(inst);}
// labels
virtual Inst*
caseLabel(Inst* inst)=0;// {return caseDefault(inst);}
// type checking
virtual Inst*
caseCatchLabelInst(Inst* inst)=0;// {return caseDefault(inst);}
// method entry/exit
virtual Inst*
caseMethodEntryLabel(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseMethodEntry(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseMethodEnd(Inst* inst)=0;// {return caseDefault(inst);}
// source markers
virtual Inst*
caseMethodMarker(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
casePhi(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauPi(TauPiInst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseIncCounter(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
casePrefetch(Inst* inst)=0;// {return caseDefault(inst);}
// compressed references
virtual Inst*
caseUncompressRef(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseCompressRef(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseLdFieldOffset(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseLdFieldOffsetPlusHeapbase(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseLdArrayBaseOffset(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseLdArrayBaseOffsetPlusHeapbase(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseLdArrayLenOffset(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseLdArrayLenOffsetPlusHeapbase(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseAddOffset(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseAddOffsetPlusHeapbase(Inst* inst)=0;// {return caseDefault(inst);}
// new tau methods
virtual Inst*
caseTauPoint(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauEdge(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauAnd(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauSafe(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauUnsafe(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauCheckCast(TypeInst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauHasType(TypeInst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauHasExactType(TypeInst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseTauIsNonNull(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseIdentHC(Inst* inst)=0;// {return caseDefault(inst);}
virtual Inst*
caseDefault(Inst* inst)=0;// {return NULL;}
protected:
Inst* dispatch(Inst*);
};
} //namespace Jitrino
#endif // _INST_H_