blob: 4845c3d1e2ddd5a20e907f8b7529a813e4f1b91c [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
* @version $Revision: 1.16.12.1.4.4 $
*
*/
#include <stdio.h>
#include "Inst.h"
#include "Type.h"
#include "IRBuilder.h"
namespace Jitrino {
//-----------------------------------------------------------------------------
// Inst constructors
//-----------------------------------------------------------------------------
Inst::Inst(Opcode opcode, Modifier mod, Type::Tag type, Opnd* dst_)
: operation(opcode, type, mod), numSrcs(0), dst(0)
{
setDst(dst_);
}
Inst::Inst(Opcode opcode, Modifier mod, Type::Tag type, Opnd* dst_, Opnd* src)
: operation(opcode, type, mod), numSrcs(1), dst(0)
{
setDst(dst_);
srcs[0] = src;
}
Inst::Inst(Opcode opcode, Modifier mod, Type::Tag type, Opnd* dst_,
Opnd* src1, Opnd* src2)
: operation(opcode, type, mod), numSrcs(2), dst(0)
{
setDst(dst_);
srcs[0] = src1;
srcs[1] = src2;
}
Inst::Inst(Opcode opcode, Modifier mod, Type::Tag type, Opnd* dst_, U_32 nSrcs)
: operation(opcode, type, mod), numSrcs(nSrcs), dst(0)
{
setDst(dst_);
}
Opnd* Inst::getSrcExtended(U_32 srcIndex) const {
assert(0);
return NULL;
}
bool Inst::isThrow() const {
return ((getOpcode() == Op_Throw) || (getOpcode() == Op_ThrowSystemException) ||
(getOpcode() == Op_ThrowLinkingException) ||
( (getOpcode() == Op_VMHelperCall) ?
(asVMHelperCallInst()->isThrowLazy()) : false ) );
}
Edge::Kind Inst::getEdgeKind(const Edge* edge) const {
#ifdef _DEBUG
Node* node = edge->getSourceNode();
Node* succ = edge->getTargetNode();
assert(node->isBlockNode());
assert(succ->isBlockNode());
assert(node->getLastInst() == this);
assert(node->getOutDegree() <= 2); //uncond + exception
#endif
return Edge::Kind_Unconditional;// jump
}
void Inst::removeRedundantBranch() {
if (getOpcode() == Op_Branch || isSwitch()) {
unlink();
}
}
//-----------------------------------------------------------------------------
// BranchInst utilities
//-----------------------------------------------------------------------------
void BranchInst::updateControlTransferInst(Node *oldTarget, Node* newTarget ) {
assert(oldTarget->getKind() == newTarget->getKind());
LabelInst* oldLabel = (LabelInst*)oldTarget->getFirstInst();
LabelInst* newLabel = (LabelInst*)newTarget->getFirstInst();
// Update source nodes branch instruction
if(getTargetLabel() == oldLabel) {
assert(newTarget->isBlockNode());
replaceTargetLabel(newLabel);
}
}
// the following utility for conditional branches will make the fallthrough the target and
// the target the fallthrough, changing the branch condition in the process
void BranchInst::swapTargets(LabelInst *target) {
ComparisonModifier modifier = getComparisonModifier();
switch (modifier) {
// binary boolean comparisons. NOTE: the operands are also swapped
case Cmp_EQ: modifier = Cmp_NE_Un; break;
case Cmp_NE_Un: modifier = Cmp_EQ; break;
case Cmp_GT: modifier = Cmp_GTE; break;
case Cmp_GT_Un: modifier = Cmp_GTE_Un; break;
case Cmp_GTE: modifier = Cmp_GT; break;
case Cmp_GTE_Un: modifier = Cmp_GT_Un; break;
// unary boolean comparisons
case Cmp_Zero: modifier = Cmp_NonZero; break;
case Cmp_NonZero: modifier = Cmp_Zero; break;
default:
assert(0);
}
setComparisonModifier(modifier);
if (getNumSrcOperands()==2) {
Opnd *src0 = getSrc(0);
Opnd *src1 = getSrc(1);
setSrc(0, src1);
setSrc(1, src0);
}
replaceTargetLabel(target);
}
Edge::Kind BranchInst::getEdgeKind(const Edge* edge) const {
Node* succ = edge->getTargetNode();
#ifdef _DEBUG
Node* node = edge->getSourceNode();
assert(node->isBlockNode());
assert(succ->isBlockNode());
assert(node->getLastInst() == this);
assert(node->getOutDegree() == 2 || (node->getOutDegree() == 3 && node->getExceptionEdge()!=NULL));
#endif
Edge::Kind kind = getTargetLabel() == succ->getFirstInst() ? Edge::Kind_True : Edge::Kind_False;
return kind;
}
// the following utility for conditional branches will return the taken edge based on the
// incoming condition. This will ignore exception edges
Edge* BranchInst::getTakenEdge(U_32 result) {
// find the node for this branch instruction
Node *node = getNode();
assert(node->getFirstInst()->isLabel());
LabelInst *targetLabel = getTargetLabel();
Edge* edge = NULL;
const Edges& edges = node->getOutEdges();
for(Edges::const_iterator eiter = edges.begin(); eiter != edges.end(); ++eiter) {
edge = *eiter;
Node * tar = edge->getTargetNode();
if ( (!tar->isDispatchNode() &&
((result == 0) && (tar->getFirstInst() != targetLabel))) ||
((result == 1) && (tar->getFirstInst() == targetLabel)) ) {
break;
}
}
assert(edge != NULL);
// was:
// std::cout << "WARNING, useless branch\n";
// if(node->getOutEdges().empty())
// return NULL;
// else
// return node->getOutEdges().front();
return edge;
}
//-----------------------------------------------------------------------------
// Inst printing methods
//-----------------------------------------------------------------------------
void Inst::print(::std::ostream& os) const {
os << "I" << (int)id << ":";
printFormatString(os, getOperation().getOpcodeFormatString());
}
void Inst::handlePrintEscape(::std::ostream& os, char code) const {
switch (code) {
case 's': // src operands
{
bool comma = false;
for (U_32 i=0; i<numSrcs; i++) {
if (comma)
os << ", ";
getSrc(i)->print(os);
comma = true;
}
}
break;
case 'a': // arguments to a virtual or indirect call
{
bool comma = false;
for (U_32 i=3; i<numSrcs; i++) {
if (comma)
os << ", ";
getSrc(i)->print(os);
comma = true;
}
}
break;
case 'b': // bytecode mapping info
{
if (getBCOffset() == ILLEGAL_BC_MAPPING_VALUE) {
Node* node = getNode();
if (node!=NULL && node->isBlockNode()) { // write 'unknown' only for block nodes
os<<"bcmap:unknown ";
}
} else {
I_32 bcOffset = (I_32)getBCOffset();
os<<"bcmap:"<<bcOffset<<" ";
}
}
break;
case 'p': // arguments to a more direct call
{
bool comma = false;
for (U_32 i=2; i<numSrcs; i++) {
if (comma)
os << ", ";
getSrc(i)->print(os);
comma = true;
}
}
break;
case 'l':
{
if (getDst()->isNull() != true)
getDst()->printWithType(os);
}
break;
case 'n': // new line
os << ::std::endl;
break;
case 'm': // modifier
os << getOperation().getModifierString();
break;
case 't': // instruction type
os << Type::getPrintString(getType());
break;
case '0':
getSrc(0)->print(os);
break;
case '1':
getSrc(1)->print(os);
break;
case '2':
getSrc(2)->print(os);
break;
case '3':
getSrc(3)->print(os);
break;
case '4':
getSrc(4)->print(os);
break;
case '5':
getSrc(5)->print(os);
break;
default:
os << '?' << code << '?';
break;
}
}
const char *messageStr(const char *string) {
if (strcmp(string, "<init>")==0)
return "_init_";
if (strcmp(string, "<clinit>")==0)
return "_clinit_";
return string;
}
void MethodEntryInst::handlePrintEscape(::std::ostream& os, char code) const {
switch (code) {
case 'd':
os << methodDesc->getParentType()->getName()
<< "::" << messageStr(methodDesc->getName());
break;
default:
Inst::handlePrintEscape(os, code);
break;
}
}
void MethodMarkerInst::handlePrintEscape(::std::ostream& os, char code) const {
switch (code) {
case 'd':
os << methodDesc->getParentType()->getName()
<< "::" << messageStr(methodDesc->getName());
break;
default:
Inst::handlePrintEscape(os, code);
break;
}
}
void LabelInst::printId(::std::ostream&os) const {
os << "L" << (int)getLabelId();
}
void LabelInst::handlePrintEscape(::std::ostream& os, char code) const {
switch (code) {
case 'l': // label
os << "L" << (int)getLabelId();
break;
default:
Inst::handlePrintEscape(os, code);
break;
}
}
void DispatchLabelInst::printId(::std::ostream&os) const {
os << "D" << (int)getLabelId();
}
void DispatchLabelInst::handlePrintEscape(::std::ostream& os, char code) const {
switch (code) {
case 'l': // label
os << "D" << (int)getLabelId();
break;
default:
Inst::handlePrintEscape(os, code);
break;
}
}
void CatchLabelInst::printId(::std::ostream&os) const {
os << "C" << (int)getLabelId();
}
void CatchLabelInst::handlePrintEscape(::std::ostream& os, char code) const {
switch (code) {
case 'l': // label
os << "C" << (int)getLabelId() << " ord:" << (int)getOrder() << " ";
getExceptionType()->print(os);
break;
default:
Inst::handlePrintEscape(os, code);
break;
}
}
void BranchInst::handlePrintEscape(::std::ostream& os, char code) const {
switch (code) {
case 'l': // label
os << "L" << (int)targetLabel->getLabelId();
break;
default:
Inst::handlePrintEscape(os, code);
break;
}
}
void ConstInst::handlePrintEscape(::std::ostream& os, char code) const {
if (code != 'c') {
Inst::handlePrintEscape(os, code);
return;
}
// print constant value
switch (getType()) {
case Type::Int32:
os << value.i4;
break;
case Type::Int64:
os << (unsigned long)value.i8;
break;
case Type::IntPtr:
case Type::UIntPtr:
case Type::UnmanagedPtr:
os << value.i;
break;
case Type::Single:
os << value.s;
break;
case Type::Double:
os << value.d;
break;
case Type::NullObject:
os << "null";
break;
case Type::CompressedNullObject:
os << "cnull";
break;
default: assert(0);
}
}
void VarAccessInst::handlePrintEscape(::std::ostream& os, char code) const {
Inst::handlePrintEscape(os, code);
}
void TokenInst::handlePrintEscape(::std::ostream& os, char code) const {
switch (code) {
case 'd': // token
os << (int)token;
break;
default:
Inst::handlePrintEscape(os, code);
break;
}
}
void FieldAccessInst::handlePrintEscape(::std::ostream& os, char code) const {
switch (code) {
case 'd':
os << fieldDesc->getParentType()->getName()
<< "::" << fieldDesc->getName();
break;
default:
Inst::handlePrintEscape(os, code);
break;
}
}
void MethodInst::handlePrintEscape(::std::ostream& os, char code) const {
switch (code) {
case 'd':
os << methodDesc->getParentType()->getName()
<< "::" << messageStr(methodDesc->getName());
break;
default:
Inst::handlePrintEscape(os, code);
break;
}
}
void JitHelperCallInst::handlePrintEscape(::std::ostream& os, char code) const {
switch(code) {
case 'd':
switch(jitHelperId) {
case Prefetch:
os << "Prefetch"; break;
case Memset0:
os << "Memset0"; break;
case InitializeArray:
os << "InitializeArray"; break;
case SaveThisState:
os << "SaveThisState"; break;
case ReadThisState:
os << "ReadThisState"; break;
case LockedCompareAndExchange:
os << "LockedCmpExchange"; break;
case AddValueProfileValue:
os << "AddValueProfileValue"; break;
case FillArrayWithConst:
os << "FillArrayWithConst"; break;
case ArrayCopyDirect:
os << "ArrayCopyDirect"; break;
case ArrayCopyReverse:
os << "ArrayCopyReverse"; break;
case StringCompareTo:
os << "StringCompareTo"; break;
case StringIndexOf:
os << "StringIndexOf"; break;
case StringRegionMatches:
os << "StringRegionMatches"; break;
case ClassIsArray:
os << "ClassIsArray"; break;
case ClassGetAllocationHandle:
os << "ClassGetAllocationHandle"; break;
case ClassGetTypeSize:
os << "ClassGetTypeSize"; break;
case ClassGetArrayElemSize:
os << "ClassGetArrayElemSize"; break;
case ClassIsInterface:
os << "ClassIsInterface"; break;
case ClassIsFinal:
os << "ClassIsFinal"; break;
case ClassGetArrayClass:
os << "ClassGetArrayClass"; break;
case ClassGetFastCheckDepth:
os << "ClassGetFastCheckDepth"; break;
default:
assert(0); break;
}
break;
default:
Inst::handlePrintEscape(os, code);
break;
}
}
void VMHelperCallInst::handlePrintEscape(::std::ostream& os, char code) const {
switch(code) {
case 'd':
{
CompilationContext* cc = CompilationContext::getCurrentContext();
const char* name = cc->getVMCompilationInterface()->getRuntimeHelperName(vmHelperId);
os <<name<<" ";
}
break;
default:
Inst::handlePrintEscape(os, code);
break;
}
}
void TypeInst::handlePrintEscape(::std::ostream& os, char code) const {
switch (code) {
case 'd': // typeDesc
type->print(os);
break;
default:
Inst::handlePrintEscape(os, code);
break;
}
}
void SwitchInst::updateControlTransferInst(Node *oldTarget, Node* newTarget ) {
assert(oldTarget->getKind() == newTarget->getKind());
LabelInst* oldLabel = (LabelInst*)oldTarget->getFirstInst();
LabelInst* newLabel = (LabelInst*)newTarget->getFirstInst();
if (getDefaultTarget() == oldLabel) {
assert(newTarget->isBlockNode());
replaceDefaultTargetLabel(newLabel);
}
U_32 n = getNumTargets();
for (U_32 i = 0; i < n; i++) {
if (getTarget(i) == oldLabel) {
assert(newTarget->isBlockNode());
replaceTargetLabel(i, newLabel);
}
}
}
Edge::Kind SwitchInst::getEdgeKind(const Edge* edge) const {
Node* succ = edge->getTargetNode();
#ifdef _DEBUG
Node* node = edge->getSourceNode();
assert(node->isBlockNode());
assert(succ->isBlockNode());
assert(node->getLastInst() == this);
#endif
Edge::Kind kind = getDefaultTarget() == succ->getFirstInst()? Edge::Kind_False : Edge::Kind_True;
return kind;
}
void SwitchInst::handlePrintEscape(::std::ostream& os, char code) const {
switch (code) {
case 'l': // target labels
{
bool comma = false;
for (U_32 i=0; i<numTargets; i++) {
if (comma)
os << ", ";
comma = true;
os << "L" << (int)targetInsts[i]->getLabelId();
}
os << ", DEF:L" << (int)defaultTargetInst->getLabelId();
}
break;
default:
Inst::handlePrintEscape(os, code);
break;
}
}
extern void printPiCondition(const PiCondition* cond, ::std::ostream &os);
void TauPiInst::handlePrintEscape(::std::ostream& os, char code) const {
switch (code) {
case 'd':
printPiCondition(cond, os);
break;
default:
Inst::handlePrintEscape(os, code);
break;
}
}
void Inst::printFormatString(::std::ostream& os, const char* formatString) const {
const char* str = formatString;
for (char c = *str; c != '\0'; c = *++str) {
if (c == '%') {
// escape
str++;
handlePrintEscape(os, *str);
continue;
}
os << c;
}
}
//-----------------------------------------------------------------------------
// Inst duplication
//-----------------------------------------------------------------------------
class CloneVisitor : public InstFormatVisitor {
private:
InstFactory& instFactory;
OpndManager& opndManager;
OpndRenameTable& renameTable;
Inst* clone;
public:
CloneVisitor(InstFactory& ifactory, OpndManager& om, OpndRenameTable& rt)
: instFactory(ifactory), opndManager(om), renameTable(rt), clone(NULL)
{
}
Inst* getClone() {return clone;}
void accept(Inst* inst) {
clone = instFactory.makeClone(inst, opndManager, renameTable);
}
void accept(LabelInst* inst) {
clone = instFactory.makeClone(inst, opndManager, renameTable);
}
void accept(DispatchLabelInst* inst) {
clone = instFactory.makeClone(inst, opndManager, renameTable);
}
void accept(CatchLabelInst* inst) {
clone = instFactory.makeClone(inst, opndManager, renameTable);
}
void accept(JitHelperCallInst* inst) {
clone = instFactory.makeClone(inst, opndManager, renameTable);
}
void accept(VMHelperCallInst* inst) {
clone = instFactory.makeClone(inst, opndManager, renameTable);
}
void accept(MethodEntryInst* inst) {
clone = instFactory.makeClone(inst, opndManager, renameTable);
}
void accept(MethodMarkerInst* inst) {
clone = instFactory.makeClone(inst, opndManager, renameTable);
}
void accept(BranchInst* inst) {
clone = instFactory.makeClone(inst, opndManager, renameTable);
}
void accept(SwitchInst* inst) {
clone = instFactory.makeClone(inst, opndManager, renameTable);
}
void accept(ConstInst* inst) {
clone = instFactory.makeClone(inst, opndManager, renameTable);
}
void accept(TokenInst* inst) {
clone = instFactory.makeClone(inst, opndManager, renameTable);
}
void accept(LinkingExcInst* inst) {
clone = instFactory.makeClone(inst, opndManager, renameTable);
}
void accept(VarAccessInst* inst) {
clone = instFactory.makeClone(inst, opndManager, renameTable);
}
void accept(TypeInst* inst) {
clone = instFactory.makeClone(inst, opndManager, renameTable);
}
void accept(FieldAccessInst* inst) {
clone = instFactory.makeClone(inst, opndManager, renameTable);
}
void accept(MethodInst* inst) {
clone = instFactory.makeClone(inst, opndManager, renameTable);
}
void accept(MethodCallInst* inst) {
clone = instFactory.makeClone(inst, opndManager, renameTable);
}
void accept(CallInst* inst) {
clone = instFactory.makeClone(inst, opndManager, renameTable);
}
void accept(PhiInst* inst) {
clone = instFactory.makeClone(inst, opndManager, renameTable);
}
void accept(TauPiInst* inst) {
clone = instFactory.makeClone(inst, opndManager, renameTable);
}
void accept(MultiSrcInst* inst) {
clone = instFactory.makeClone(inst, opndManager, renameTable);
}
};
Inst*
InstFactory::clone(Inst* inst, OpndManager& opndManager, OpndRenameTable *table) {
CloneVisitor cloneVisitor(*this, opndManager, *table);
inst->visit(cloneVisitor);
Inst* newInst = cloneVisitor.getClone();
newInst->setBCOffset(inst->getBCOffset());
return newInst;
}
Inst*
InstFactory::makeClone(Inst* inst,
OpndManager& opndManager,
OpndRenameTable& table) {
Inst *newInst = NULL;
switch(inst->getNumSrcOperands()) {
case 0:
newInst = makeInst(inst->getOpcode(),
inst->getModifier(),
inst->getType(),
table.duplicate(opndManager, inst->getDst()));
break;
case 1:
newInst = makeInst(inst->getOpcode(),
inst->getModifier(),
inst->getType(),
table.duplicate(opndManager, inst->getDst()),
table.rename(inst->getSrc(0)));
break;
case 2:
newInst = makeInst(inst->getOpcode(),
inst->getModifier(),
inst->getType(),
table.duplicate(opndManager, inst->getDst()),
table.rename(inst->getSrc(0)),
table.rename(inst->getSrc(1)));
break;
default:
assert(0);
}
newInst->setPersistentInstructionId(inst->getPersistentInstructionId());
return newInst;
}
LabelInst*
InstFactory::makeClone(LabelInst* inst, OpndManager& opndManager, OpndRenameTable& table) {
LabelInst *newInst = makeLabel();
newInst->setPersistentInstructionId(inst->getPersistentInstructionId());
return newInst;
}
DispatchLabelInst*
InstFactory::makeClone(DispatchLabelInst* inst, OpndManager& opndManager, OpndRenameTable& table) {
assert(0);
return NULL;
}
CatchLabelInst*
InstFactory::makeClone(CatchLabelInst* inst,
OpndManager& opndManager,
OpndRenameTable& table) {
CatchLabelInst *newInst =makeCatchLabelInst(createLabelNumber(),
inst->getOrder(), inst->getExceptionType());
newInst->setPersistentInstructionId(inst->getPersistentInstructionId());
return newInst;
}
MethodEntryInst*
InstFactory::makeClone(MethodEntryInst* inst,
OpndManager& opndManager,
OpndRenameTable& table) {
MethodEntryInst *newInst = makeMethodEntryInst(createLabelNumber(),
inst->methodDesc);
newInst->setPersistentInstructionId(inst->getPersistentInstructionId());
return newInst;
}
MethodMarkerInst*
InstFactory::makeClone(MethodMarkerInst* inst,
OpndManager& opndManager,
OpndRenameTable& table) {
MethodMarkerInst *newInst = NULL;
if (inst->getNumSrcOperands() > 0) {
newInst = makeMethodMarkerInst(inst->kind, inst->methodDesc,
table.rename(inst->getSrc(0)));
} else {
newInst = makeMethodMarkerInst(inst->kind, inst->methodDesc);
}
newInst->setPersistentInstructionId(inst->getPersistentInstructionId());
return newInst;
}
BranchInst*
InstFactory::makeClone(BranchInst* inst, OpndManager& opndManager, OpndRenameTable& table) {
BranchInst *newInst = NULL;
switch (inst->getNumSrcOperands()) {
case 0:
newInst = makeBranchInst(inst->getOpcode(), inst->getTargetLabel());
break;
case 1:
newInst = makeBranchInst(inst->getOpcode(),
inst->getComparisonModifier(),
inst->getType(),
table.rename(inst->getSrc(0)),
inst->getTargetLabel());
break;
case 2:
newInst = makeBranchInst(inst->getOpcode(),
inst->getComparisonModifier(),
inst->getType(),
table.rename(inst->getSrc(0)),
table.rename(inst->getSrc(1)),
inst->getTargetLabel());
break;
default: assert(0);
}
newInst->setPersistentInstructionId(inst->getPersistentInstructionId());
return newInst;
}
SwitchInst*
InstFactory::makeClone(SwitchInst* inst,
OpndManager& opndManager,
OpndRenameTable& table) {
Opnd* src = table.rename(inst->getSrc(0));
U_32 numTargets = inst->getNumTargets();
LabelInst** targets = inst->getTargets();
LabelInst** newTargets = new (memManager) LabelInst*[numTargets];
for(U_32 i = 0; i < numTargets; ++i)
newTargets[i] = targets[i];
SwitchInst *newInst = makeSwitchInst(src, newTargets, numTargets, inst->getDefaultTarget());
newInst->setPersistentInstructionId(inst->getPersistentInstructionId());
return newInst;
}
ConstInst*
InstFactory::makeClone(ConstInst* inst,
OpndManager& opndManager,
OpndRenameTable& table) {
ConstInst *newInst = NULL;
switch(inst->getType()) {
case Type::Int32:
newInst = makeConstInst(table.duplicate(opndManager, inst->getDst()),
inst->getValue().i4);
break;
case Type::Int64:
newInst = makeConstInst(table.duplicate(opndManager, inst->getDst()),
inst->getValue().i8);
break;
case Type::Single:
newInst = makeConstInst(table.duplicate(opndManager, inst->getDst()),
inst->getValue().s);
break;
case Type::Double:
newInst = makeConstInst(table.duplicate(opndManager, inst->getDst()),
inst->getValue().d);
break;
case Type::UnmanagedPtr:
{
ConstInst::ConstValue v;
v.i8 = inst->getValue().i8;
newInst = makeConstInst(table.duplicate(opndManager, inst->getDst()), v);
}
break;
case Type::NullObject:
newInst = makeConstInst(table.duplicate(opndManager, inst->getDst()));
break;
case Type::CompressedNullObject:
newInst = makeConstInst(table.duplicate(opndManager, inst->getDst()));
break;
default: assert(0);
}
newInst->setPersistentInstructionId(inst->getPersistentInstructionId());
return newInst;
}
TokenInst*
InstFactory::makeClone(TokenInst* inst,
OpndManager& opndManager,
OpndRenameTable& table) {
TokenInst *newInst = makeTokenInst(inst->getOpcode(),
inst->getModifier(),
inst->getType(),
table.duplicate(opndManager, inst->getDst()),
inst->getToken(),
inst->getEnclosingMethod());
newInst->setPersistentInstructionId(inst->getPersistentInstructionId());
return newInst;
}
LinkingExcInst*
InstFactory::makeClone(LinkingExcInst* inst,
OpndManager& opndManager,
OpndRenameTable& table) {
LinkingExcInst *newInst = makeLinkingExcInst(inst->getOpcode(),
inst->getModifier(),
inst->getType(),
table.duplicate(opndManager, inst->getDst()),
inst->getEnclosingClass(),
inst->getCPIndex(),
inst->getOperation());
newInst->setPersistentInstructionId(inst->getPersistentInstructionId());
return newInst;
}
VarAccessInst*
InstFactory::makeClone(VarAccessInst* inst,
OpndManager& opndManager,
OpndRenameTable& table) {
VarAccessInst *newInst = NULL;
if (inst->getOpcode() == Op_StVar) {
if (inst->getDst()->isVarOpnd()) {
newInst = makeVarAccessInst(inst->getOpcode(),
inst->getType(),
table.duplicate(opndManager, inst->getDst())->asVarOpnd(),
table.rename(inst->getSrc(0)));
} else {
newInst = makeVarAccessInst(inst->getOpcode(),
inst->getType(),
table.duplicate(opndManager, inst->getDst())->asSsaVarOpnd(),
table.rename(inst->getSrc(0)));
}
} else {
if (inst->getSrc(0)->isVarOpnd()) {
newInst = makeVarAccessInst(inst->getOpcode(),
inst->getType(),
table.duplicate(opndManager, inst->getDst()),
table.rename(inst->getSrc(0))->asVarOpnd());
} else {
newInst = makeVarAccessInst(inst->getOpcode(),
inst->getType(),
table.duplicate(opndManager, inst->getDst()),
table.rename(inst->getSrc(0))->asSsaVarOpnd());
}
}
newInst->setPersistentInstructionId(inst->getPersistentInstructionId());
return newInst;
}
TypeInst*
InstFactory::makeClone(TypeInst* inst, OpndManager& opndManager, OpndRenameTable& table) {
Opcode opc = inst->getOpcode();
Modifier mod = inst->getModifier();
Type::Tag tag = inst->getType();
Opnd* dst = table.duplicate(opndManager, inst->getDst());
U_32 numSrcs = inst->getNumSrcOperands();
TypeInst *newInst = NULL;
switch(inst->getNumSrcOperands()) {
case 0:
newInst = makeTypeInst(opc, mod, tag, dst, inst->getTypeInfo());
break;
case 1:
newInst = makeTypeInst(opc, mod, tag, dst,table.rename(inst->getSrc(0)), inst->getTypeInfo());
break;
case 2:
newInst = makeTypeInst(opc, mod, tag, dst, table.rename(inst->getSrc(0)), table.rename(inst->getSrc(1)),
inst->getTypeInfo());
break;
default:
Opnd** opnds = new (memManager) Opnd*[numSrcs];
for (U_32 i=0; i<numSrcs; i++)
opnds[i] = table.rename(inst->getSrc(i));
newInst = makeTypeInst(opc, mod, tag, dst, numSrcs, opnds, inst->getTypeInfo());
break;
}
newInst->setPersistentInstructionId(inst->getPersistentInstructionId());
return newInst;
}
FieldAccessInst*
InstFactory::makeClone(FieldAccessInst* inst, OpndManager& opndManager, OpndRenameTable& table) {
Opcode opc = inst->getOpcode();
Modifier mod = inst->getModifier();
Type::Tag tag = inst->getType();
Opnd* dst = table.duplicate(opndManager, inst->getDst());
U_32 numSrcs = inst->getNumSrcOperands();
FieldAccessInst *newInst = NULL;
switch(inst->getNumSrcOperands()) {
case 0:
newInst = makeFieldAccessInst(opc, mod, tag, dst, inst->fieldDesc);
break;
case 1:
newInst = makeFieldAccessInst(opc, mod, tag, dst, table.rename(inst->getSrc(0)),
inst->fieldDesc);
break;
case 2:
newInst = makeFieldAccessInst(opc, mod, tag, dst, table.rename(inst->getSrc(0)),
table.rename(inst->getSrc(1)), inst->fieldDesc);
break;
default:
Opnd** opnds = new (memManager) Opnd*[numSrcs];
for (U_32 i=0; i<numSrcs; i++)
opnds[i] = table.rename(inst->getSrc(i));
newInst = makeFieldAccessInst(opc, mod, tag, dst, numSrcs, opnds, inst->fieldDesc);
break;
}
newInst->setPersistentInstructionId(inst->getPersistentInstructionId());
return newInst;
}
MethodInst*
InstFactory::makeClone(MethodInst* inst,
OpndManager& opndManager,
OpndRenameTable& table) {
Opcode opc = inst->getOpcode();
Modifier mod = inst->getModifier();
Type::Tag tag = inst->getType();
Opnd* dst = table.duplicate(opndManager, inst->getDst());
U_32 numSrcs = inst->getNumSrcOperands();
MethodInst *newInst = NULL;
switch(inst->getNumSrcOperands()) {
case 0:
newInst = makeMethodInst(opc, mod, tag, dst, inst->methodDesc);
break;
case 1:
newInst = makeMethodInst(opc, mod, tag, dst, table.rename(inst->getSrc(0)),
inst->methodDesc);
break;
default:
Opnd** opnds = new (memManager) Opnd*[numSrcs];
for (U_32 i=0; i<numSrcs; i++)
opnds[i] = table.rename(inst->getSrc(i));
newInst = makeMethodInst(opc, mod, tag, dst, numSrcs, opnds, inst->methodDesc);
break;
}
newInst->setPersistentInstructionId(inst->getPersistentInstructionId());
return newInst;
}
MethodCallInst*
InstFactory::makeClone(MethodCallInst* inst,
OpndManager& opndManager,
OpndRenameTable& table) {
U_32 nsrcs = inst->getNumSrcOperands();
Opnd** newArgs = new (memManager) Opnd*[nsrcs];
for (U_32 i=0; i<nsrcs; i++)
newArgs[i] = table.rename(inst->getSrc(i));
MethodCallInst *newInst
= makeMethodCallInst(inst->getOpcode(),
inst->getModifier(),
inst->getType(),
table.duplicate(opndManager, inst->getDst()),
nsrcs,
newArgs,
inst->getMethodDesc());
newInst->setPersistentInstructionId(inst->getPersistentInstructionId());
return newInst;
}
CallInst*
InstFactory::makeClone(CallInst* inst,
OpndManager& opndManager,
OpndRenameTable& table) {
U_32 numArgs = inst->getNumArgs();
Opnd** newArgs = new (memManager) Opnd*[numArgs];
for (U_32 i=0; i<numArgs; i++)
newArgs[i] = table.rename(inst->getArg(i));
CallInst *newInst = makeCallInst(inst->getOpcode(),
inst->getModifier(),
inst->getType(),
table.duplicate(opndManager, inst->getDst()),
table.rename(inst->getFunPtr()),
inst->getNumArgs(),
newArgs);
newInst->setPersistentInstructionId(inst->getPersistentInstructionId());
return newInst;
}
JitHelperCallInst*
InstFactory::makeClone(JitHelperCallInst* inst,
OpndManager& opndManager,
OpndRenameTable& table)
{
U_32 nsrcs = inst->getNumSrcOperands();
Opnd** newArgs = new (memManager) Opnd*[nsrcs];
for (U_32 i=0; i<nsrcs; i++){
newArgs[i] = table.rename(inst->getSrc(i));
}
JitHelperCallInst *newInst = makeJitHelperCallInst(inst->getOpcode(),
inst->getModifier(),
inst->getType(),
table.duplicate(opndManager, inst->getDst()),
nsrcs,
newArgs,
inst->getJitHelperId());
newInst->setPersistentInstructionId(inst->getPersistentInstructionId());
return newInst;
}
VMHelperCallInst*
InstFactory::makeClone(VMHelperCallInst* inst,
OpndManager& opndManager,
OpndRenameTable& table)
{
U_32 nsrcs = inst->getNumSrcOperands();
Opnd** newArgs = new (memManager) Opnd*[nsrcs];
for (U_32 i=0; i<nsrcs; i++){
newArgs[i] = table.rename(inst->getSrc(i));
}
VMHelperCallInst *newInst = makeVMHelperCallInst(inst->getOpcode(),
inst->getModifier(),
inst->getType(),
table.duplicate(opndManager, inst->getDst()),
nsrcs,
newArgs,
inst->getVMHelperId());
newInst->setPersistentInstructionId(inst->getPersistentInstructionId());
return newInst;
}
PhiInst*
InstFactory::makeClone(PhiInst* inst, OpndManager& opndManager, OpndRenameTable& table) {
U_32 numArgs = inst->getNumSrcOperands();
Opnd** newArgs = new (memManager) Opnd*[numArgs];
for (U_32 i=0; i<numArgs; i++)
newArgs[i] = table.rename(inst->getSrc(i));
PhiInst *newInst = makePhiInst(inst->getType(),
table.duplicate(opndManager, inst->getDst()),
numArgs,
newArgs);
newInst->setPersistentInstructionId(inst->getPersistentInstructionId());
return newInst;
}
MultiSrcInst*
InstFactory::makeClone(MultiSrcInst* inst, OpndManager& opndManager, OpndRenameTable& table) {
Opcode opc = inst->getOpcode();
Modifier mod = inst->getModifier();
Type::Tag tag = inst->getType();
Opnd* dst = table.duplicate(opndManager, inst->getDst());
U_32 numSrcs = inst->getNumSrcOperands();
MultiSrcInst *newInst;
switch(numSrcs) {
case 0:
newInst = makeMultiSrcInst(opc, mod, tag, dst);
break;
case 1:
newInst = makeMultiSrcInst(opc, mod, tag, dst,table.rename(inst->getSrc(0)));
break;
case 2:
newInst = makeMultiSrcInst(opc, mod, tag, dst, table.rename(inst->getSrc(0)), table.rename(inst->getSrc(1)));
break;
default:
Opnd** opnds = new (memManager) Opnd*[numSrcs];
for (U_32 i=0; i<numSrcs; i++)
opnds[i] = table.rename(inst->getSrc(i));
newInst = makeMultiSrcInst(opc, mod, tag, dst, numSrcs, opnds);
break;
}
newInst->setPersistentInstructionId(inst->getPersistentInstructionId());
return newInst;
}
//-----------------------------------------------------------------------------
// InstFactory methods
//-----------------------------------------------------------------------------
InstFactory::InstFactory(MemoryManager& mm, MethodDesc &md) : memManager(mm) {
maxNumLabels = 0;
numInsts = 0;
}
Opnd**
InstFactory::copyOpnds(Opnd** srcs, U_32 numSrcs) {
Opnd** newSrcs = new (memManager) Opnd*[numSrcs];
for (U_32 i=0; i<numSrcs; i++)
newSrcs[i] = srcs[i];
return newSrcs;
}
Opnd**
InstFactory::copyOpnds(Opnd* src1, Opnd** srcs, U_32 numSrcs) {
Opnd** newSrcs = new (memManager) Opnd*[numSrcs+1];
newSrcs[0] = src1;
for (U_32 i=0; i<numSrcs; i++)
newSrcs[i+1] = srcs[i];
return newSrcs;
}
Opnd**
InstFactory::copyOpnds(Opnd* src1, Opnd* src2, Opnd** srcs, U_32 numSrcs) {
Opnd** newSrcs = new (memManager) Opnd*[numSrcs+2];
newSrcs[0] = src1;
newSrcs[1] = src2;
for (U_32 i=0; i<numSrcs; i++)
newSrcs[i+2] = srcs[i];
return newSrcs;
}
void
InstFactory::appendSrc(MultiSrcInst *inst, Opnd *opnd) {
U_32 oldNumSrcs = inst->numSrcs;
U_32 newNumSrcs = inst->numSrcs+1;
if (newNumSrcs > MAX_INST_SRCS) {
// an extended source
U_32 oldExtendedSrcs = oldNumSrcs - MAX_INST_SRCS;
U_32 newExtendedSrcs = newNumSrcs - MAX_INST_SRCS;
if (newExtendedSrcs <= inst->extendedSrcSpace) {
// fits in existing memory
inst->extendedSrcs[oldExtendedSrcs] = opnd;
} else {
// need to allocate more memory
U_32 newSpace = newExtendedSrcs * 2;
Opnd** opnds = new (memManager) Opnd*[newSpace];
Opnd** oldOpnds = inst->extendedSrcs;
// copy existing opnds
U_32 j;
for (j = 0; j < oldExtendedSrcs; j++)
opnds[j] = oldOpnds[j];
opnds[j++] = opnd;
inst->extendedSrcs = opnds;
inst->extendedSrcSpace = newSpace;
}
inst->numSrcs = newNumSrcs;
} else {
// fits in the normal sources
inst->numSrcs = newNumSrcs;
inst->setSrc(oldNumSrcs, opnd);
}
}
//-----------------------------------------------------------------------------
// InstFactory factory methods for different instruction formats. All Inst
// generation should use one of these factory methods.
//-----------------------------------------------------------------------------
Inst*
InstFactory::makeInst(Opcode op, Modifier mod, Type::Tag type, Opnd* dst) {
Inst* inst = new (memManager) Inst(op, mod, type, dst);
inst->id = numInsts++;
return inst;
}
Inst*
InstFactory::makeInst(Opcode op, Modifier mod, Type::Tag type, Opnd* dst, Opnd* src) {
Inst* inst = new (memManager) Inst(op, mod, type, dst, src);
inst->id = numInsts++;
return inst;
}
Inst*
InstFactory::makeInst(Opcode op,
Modifier mod,
Type::Tag type,
Opnd* dst,
Opnd* src1,
Opnd* src2) {
Inst* inst = new (memManager) Inst(op, mod, type, dst, src1, src2);
inst->id = numInsts++;
return inst;
}
LabelInst*
InstFactory::makeLabelInst(U_32 labelId) {
LabelInst* inst = new (memManager) LabelInst(labelId);
inst->id = numInsts++;
return inst;
}
LabelInst*
InstFactory::makeLabelInst(Opcode opc, U_32 labelId) {
LabelInst* inst = new (memManager) LabelInst(opc, labelId);
inst->id = numInsts++;
return inst;
}
DispatchLabelInst*
InstFactory::makeDispatchLabelInst(U_32 labelId) {
DispatchLabelInst* inst = new (memManager) DispatchLabelInst(labelId);
inst->id = numInsts++;
return inst;
}
CatchLabelInst *
InstFactory::makeCatchLabelInst(U_32 labelId,
U_32 ord,
Type *exceptionType) {
CatchLabelInst* inst = new (memManager) CatchLabelInst(labelId, ord, exceptionType);
inst->id = numInsts++;
return inst;
}
MethodEntryInst*
InstFactory::makeMethodEntryInst(U_32 labelId, MethodDesc* md) {
MethodEntryInst* inst = new (memManager) MethodEntryInst(labelId, md);
inst->id = numInsts++;
return inst;
}
MethodMarkerInst*
InstFactory::makeMethodMarkerInst(MethodMarkerInst::Kind k, MethodDesc* md,
Opnd *obj, Opnd *retOpnd) {
assert(obj && !obj->isNull());
MethodMarkerInst* inst = new (memManager) MethodMarkerInst(k, md, obj, retOpnd);
inst->id = numInsts++;
return inst;
}
MethodMarkerInst*
InstFactory::makeMethodMarkerInst(MethodMarkerInst::Kind k, MethodDesc* md,
Opnd *retOpnd) {
MethodMarkerInst* inst = new (memManager) MethodMarkerInst(k, md, retOpnd);
inst->id = numInsts++;
return inst;
}
MethodMarkerInst*
InstFactory::makeMethodMarkerInst(MethodMarkerInst::Kind k, MethodDesc* md) {
MethodMarkerInst* inst = new (memManager) MethodMarkerInst(k, md);
inst->id = numInsts++;
return inst;
}
BranchInst*
InstFactory::makeBranchInst(Opcode op, LabelInst* target) {
BranchInst* inst = new (memManager) BranchInst(op, target);
inst->id = numInsts++;
return inst;
}
BranchInst*
InstFactory::makeBranchInst(Opcode op,
Opnd* src,
LabelInst* target) {
BranchInst* inst = new (memManager) BranchInst(op, src, target);
inst->id = numInsts++;
return inst;
}
BranchInst*
InstFactory::makeBranchInst(Opcode op,
ComparisonModifier mod,
Type::Tag type,
Opnd* src,
LabelInst* target) {
BranchInst* inst = new (memManager) BranchInst(op, mod, type, src, target);
inst->id = numInsts++;
return inst;
}
BranchInst*
InstFactory::makeBranchInst(Opcode op,
ComparisonModifier mod,
Type::Tag type,
Opnd* src1,
Opnd* src2,
LabelInst* target) {
BranchInst* inst = new (memManager) BranchInst(op, mod, type, src1, src2, target);
inst->id = numInsts++;
return inst;
}
SwitchInst*
InstFactory::makeSwitchInst(Opnd* src, LabelInst** targets, U_32 nTargets,
LabelInst* defTarget) {
SwitchInst* inst = new (memManager) SwitchInst(src, targets, nTargets, defTarget);
inst->id = numInsts++;
return inst;
}
ConstInst*
InstFactory::makeConstInst(Opnd* dst, I_32 i4) {
ConstInst* inst = new (memManager) ConstInst(dst, i4);
inst->id = numInsts++;
return inst;
}
ConstInst*
InstFactory::makeConstInst(Opnd* dst, int64 i8) {
ConstInst* inst = new (memManager) ConstInst(dst, i8);
inst->id = numInsts++;
return inst;
}
ConstInst*
InstFactory::makeConstInst(Opnd* dst, float fs) {
ConstInst* inst = new (memManager) ConstInst(dst, fs);
inst->id = numInsts++;
return inst;
}
ConstInst*
InstFactory::makeConstInst(Opnd* dst, double fd) {
ConstInst* inst = new (memManager) ConstInst(dst, fd);
inst->id = numInsts++;
return inst;
}
ConstInst*
InstFactory::makeConstInst(Opnd* dst, ConstInst::ConstValue val) {
ConstInst* inst = new (memManager) ConstInst(dst, val);
inst->id = numInsts++;
return inst;
}
ConstInst*
InstFactory::makeConstInst(Opnd* dst) {
ConstInst* inst = new (memManager) ConstInst(dst);
inst->id = numInsts++;
return inst;
}
TokenInst*
InstFactory::makeTokenInst(Opcode opc, Modifier mod, Type::Tag type, Opnd* dst, U_32 t, MethodDesc* encMethod) {
TokenInst* inst = new (memManager) TokenInst(opc, mod, type, dst, t, encMethod);
inst->id = numInsts++;
return inst;
}
LinkingExcInst*
InstFactory::makeLinkingExcInst(Opcode opc, Modifier mod, Type::Tag type, Opnd* dst,
Class_Handle encClass, U_32 CPIndex, U_32 operation) {
LinkingExcInst* inst =
new (memManager) LinkingExcInst(opc, mod, type, dst, encClass, CPIndex, operation);
inst->id = numInsts++;
return inst;
}
VarAccessInst*
InstFactory::makeVarAccessInst(Opcode op, Type::Tag type, Opnd* dst, VarOpnd* var) {
VarAccessInst* inst = new (memManager) VarAccessInst(op, type, dst, var);
inst->id = numInsts++;
return inst;
}
VarAccessInst*
InstFactory::makeVarAccessInst(Opcode op, Type::Tag type, VarOpnd* var, Opnd* src) {
VarAccessInst* inst = new (memManager) VarAccessInst(op, type, var, src);
inst->id = numInsts++;
return inst;
}
VarAccessInst*
InstFactory::makeVarAccessInst(Opcode op, Type::Tag type, Opnd* dst, SsaVarOpnd* var) {
VarAccessInst* inst = new (memManager) VarAccessInst(op, type, dst, var);
inst->id = numInsts++;
return inst;
}
VarAccessInst*
InstFactory::makeVarAccessInst(Opcode op, Type::Tag type, SsaVarOpnd* var, Opnd* src) {
VarAccessInst* inst = new (memManager) VarAccessInst(op, type, var, src);
inst->id = numInsts++;
return inst;
}
TypeInst*
InstFactory::makeTypeInst(Opcode op, Modifier mod, Type::Tag ty, Opnd* dst, Type* td) {
TypeInst* inst = new (memManager) TypeInst(op, mod, ty, dst, td);
inst->id = numInsts++;
return inst;
}
TypeInst*
InstFactory::makeTypeInst(Opcode op, Modifier mod, Type::Tag ty, Opnd* dst,
Opnd* src, Type* td) {
TypeInst* inst = new (memManager) TypeInst(op, mod, ty, dst, src, td);
inst->id = numInsts++;
return inst;
}
TypeInst*
InstFactory::makeTypeInst(Opcode op, Modifier mod, Type::Tag ty, Opnd* dst,
Opnd* src1, Opnd* src2, Type* td) {
TypeInst* inst = new (memManager) TypeInst(op, mod, ty, dst, src1, src2, td);
inst->id = numInsts++;
return inst;
}
TypeInst*
InstFactory::makeTypeInst(Opcode op, Modifier mod, Type::Tag ty, Opnd* dst,
Opnd* src1, Opnd* src2, Opnd* src3, Type* td) {
Opnd* srcs_local[3] = { src1, src2, src3 };
Opnd** srcs = copyOpnds(srcs_local, 3);
TypeInst* inst = new (memManager) TypeInst(op, mod, ty, dst, 3, srcs, td);
inst->id = numInsts++;
return inst;
}
TypeInst*
InstFactory::makeTypeInst(Opcode op, Modifier mod, Type::Tag ty, Opnd* dst,
Opnd* src1, Opnd* src2, Opnd* src3, Opnd* src4, Type* td) {
Opnd* srcs_local[4] = { src1, src2, src3, src4 };
Opnd** srcs = copyOpnds(srcs_local, 4);
TypeInst* inst = new (memManager) TypeInst(op, mod, ty, dst, 4, srcs, td);
inst->id = numInsts++;
return inst;
}
TypeInst*
InstFactory::makeTypeInst(Opcode op, Modifier mod, Type::Tag ty, Opnd* dst,
U_32 nArgs, Opnd** args_, Type* td) {
TypeInst* inst = new (memManager) TypeInst(op, mod, ty, dst, nArgs, args_, td);
inst->id = numInsts++;
return inst;
}
FieldAccessInst*
InstFactory::makeFieldAccessInst(Opcode op,
Modifier mod,
Type::Tag type,
Opnd* dst,
FieldDesc* fd) {
FieldAccessInst* inst = new (memManager) FieldAccessInst(op, mod, type, dst, fd);
inst->id = numInsts++;
return inst;
}
FieldAccessInst*
InstFactory::makeFieldAccessInst(Opcode op,
Modifier mod,
Type::Tag type,
Opnd* dst,
Opnd* src,
FieldDesc* fd) {
FieldAccessInst* inst = new (memManager) FieldAccessInst(op, mod, type, dst, src, fd);
inst->id = numInsts++;
return inst;
}
FieldAccessInst*
InstFactory::makeFieldAccessInst(Opcode op,
Modifier mod,
Type::Tag type,
Opnd* dst,
Opnd* src1,
Opnd* src2,
FieldDesc* fd) {
FieldAccessInst* inst = new (memManager) FieldAccessInst(op, mod, type, dst, src1, src2, fd);
inst->id = numInsts++;
return inst;
}
FieldAccessInst*
InstFactory::makeFieldAccessInst(Opcode op,
Modifier mod,
Type::Tag type,
Opnd* dst,
U_32 numSrcs,
Opnd** srcs,
FieldDesc* fd) {
srcs = copyOpnds(srcs, numSrcs);
FieldAccessInst* inst = new (memManager) FieldAccessInst(op, mod, type, dst, numSrcs, srcs, fd);
inst->id = numInsts++;
return inst;
}
MethodInst*
InstFactory::makeMethodInst(Opcode op, Modifier mod, Type::Tag type, Opnd* dst, MethodDesc* md) {
MethodInst* inst = new (memManager) MethodInst(op, mod, type, dst, md);
inst->id = numInsts++;
return inst;
}
MethodInst*
InstFactory::makeMethodInst(Opcode op, Modifier mod, Type::Tag type, Opnd* dst, Opnd* base, MethodDesc* md) {
MethodInst* inst = new (memManager) MethodInst(op, mod, type, dst, base, md);
inst->id = numInsts++;
return inst;
}
MethodInst*
InstFactory::makeMethodInst(Opcode op, Modifier mod, Type::Tag type, Opnd* dst, Opnd* base,
Opnd* tauHasMethod, MethodDesc* md) {
assert(tauHasMethod->getType()->tag == Type::Tau);
MethodInst* inst = new (memManager) MethodInst(op, mod, type, dst, base, tauHasMethod, md);
inst->id = numInsts++;
return inst;
}
MethodInst*
InstFactory::makeMethodInst(Opcode op,
Modifier mod,
Type::Tag type,
Opnd* dst,
U_32 nArgs,
MethodDesc* md) {
MethodInst* inst = new (memManager) MethodInst(op, mod, type, dst, nArgs, 0, md);
inst->id = numInsts++;
return inst;
}
MethodInst*
InstFactory::makeMethodInst(Opcode op,
Modifier mod,
Type::Tag type,
Opnd* dst,
U_32 numSrcs,
Opnd** srcs,
MethodDesc* md) {
srcs = copyOpnds(srcs, numSrcs);
MethodInst* inst = new (memManager) MethodInst(op, mod, type, dst, numSrcs, srcs, md);
inst->id = numInsts++;
return inst;
}
MethodCallInst*
InstFactory::makeMethodCallInst(Opcode op, Modifier mod,
Type::Tag type,
Opnd* dst,
U_32 numArgs,
Opnd** args,
MethodDesc* md) {
MethodCallInst* inst = new (memManager) MethodCallInst(op, mod, type, dst, numArgs, args, md, memManager);
inst->id = numInsts++;
return inst;
}
CallInst*
InstFactory::makeCallInst(Opcode op, Modifier mod,
Type::Tag type,
Opnd* dst,
Opnd* funptr,
U_32 numArgs,
Opnd** args) {
CallInst* inst = new (memManager) CallInst(op, mod, type, dst, funptr, numArgs, args, memManager);
inst->id = numInsts++;
return inst;
}
JitHelperCallInst*
InstFactory::makeJitHelperCallInst(Opcode op,
Modifier mod,
Type::Tag type,
Opnd* dst,
U_32 nArgs,
Opnd** args_,
JitHelperCallId id) {
JitHelperCallInst * inst =
new (memManager) JitHelperCallInst(op, mod, type, dst, nArgs, args_, id);
inst->id = numInsts++;
return inst;
}
VMHelperCallInst*
InstFactory::makeVMHelperCallInst(Opcode op,
Modifier mod,
Type::Tag type,
Opnd* dst,
U_32 nArgs,
Opnd** args_,
VM_RT_SUPPORT id) {
VMHelperCallInst * inst =
new (memManager) VMHelperCallInst(op, mod, type, dst, nArgs, args_, id);
inst->id = numInsts++;
return inst;
}
PhiInst*
InstFactory::makePhiInst(Type::Tag type, Opnd* dst, U_32 nArgs, Opnd** args_) {
#ifdef BRM_CHECK_TYPES
for (U_32 i=0; i<nArgs; ++i) {
assert(args_[i]->getType() == dst->getType());
}
#endif
PhiInst* inst = new (memManager) PhiInst(type, dst, nArgs, args_);
inst->id = numInsts++;
return inst;
}
MultiSrcInst*
InstFactory::makeMultiSrcInst(Opcode opc,
Modifier mod,
Type::Tag ty,
Opnd* dst) {
MultiSrcInst* inst = new (memManager) MultiSrcInst(opc, mod, ty, dst);
inst->id = numInsts++;
return inst;
}
MultiSrcInst*
InstFactory::makeMultiSrcInst(Opcode opc,
Modifier mod,
Type::Tag ty,
Opnd* dst,
Opnd* src) {
MultiSrcInst* inst = new (memManager) MultiSrcInst(opc, mod, ty, dst, src);
inst->id = numInsts++;
return inst;
}
MultiSrcInst*
InstFactory::makeMultiSrcInst(Opcode opc,
Modifier mod,
Type::Tag ty,
Opnd* dst,
Opnd* src1,
Opnd* src2) {
MultiSrcInst* inst = new (memManager) MultiSrcInst(opc, mod, ty, dst, src1, src2);
inst->id = numInsts++;
return inst;
}
MultiSrcInst*
InstFactory::makeMultiSrcInst(Opcode opc,
Modifier mod,
Type::Tag ty,
Opnd* dst,
Opnd* src1,
Opnd* src2,
Opnd* src3) {
Opnd* localSrcs[3] = {src1, src2, src3};
Opnd** srcs = copyOpnds(localSrcs, 3);
return makeMultiSrcInst(opc, mod, ty, dst, 3, srcs);
}
MultiSrcInst*
InstFactory::makeMultiSrcInst(Opcode opc,
Modifier mod,
Type::Tag ty,
Opnd* dst,
Opnd* src1,
Opnd* src2,
Opnd* src3,
Opnd* src4) {
Opnd* localSrcs[4] = {src1, src2, src3, src4};
Opnd** srcs = copyOpnds(localSrcs, 4);
return makeMultiSrcInst(opc, mod, ty, dst, 4, srcs);
}
MultiSrcInst*
InstFactory::makeMultiSrcInst(Opcode opc,
Modifier mod,
Type::Tag ty,
Opnd* dst,
U_32 nSrcs,
Opnd** srcs) {
MultiSrcInst* inst = new (memManager) MultiSrcInst(opc, mod, ty, dst, nSrcs, srcs);
inst->id = numInsts++;
return inst;
}
//-----------------------------------------------------------------------------
// InstFactory factory methods for different opcodes
//-----------------------------------------------------------------------------
LabelInst*
InstFactory::makeMethodEntryLabel(MethodDesc* methodDesc) {
return makeMethodEntryInst(createLabelNumber(), methodDesc);
}
Inst*
InstFactory::makeMethodMarker(MethodMarkerInst::Kind kind, MethodDesc* methodDesc,
Opnd *obj, Opnd *retOpnd) {
assert(obj && !obj->isNull());
return makeMethodMarkerInst(kind, methodDesc, obj,
retOpnd != NULL ? retOpnd : OpndManager::getNullOpnd());
}
Inst*
InstFactory::makeMethodMarker(MethodMarkerInst::Kind kind, MethodDesc* methodDesc,
Opnd *retOpnd) {
return makeMethodMarkerInst(kind, methodDesc,
retOpnd != NULL ? retOpnd : OpndManager::getNullOpnd());
}
Inst*
InstFactory::makeMethodMarker(MethodMarkerInst::Kind kind, MethodDesc* methodDesc) {
return makeMethodMarkerInst(kind, methodDesc);
}
// Numeric compute
Inst*
InstFactory::makeAdd(Modifier mod, Opnd* dst, Opnd* src1, Opnd* src2) {
return makeInst(Op_Add, mod, dst->getType()->tag, dst, src1, src2);
}
Inst*
InstFactory::makeSub(Modifier mod, Opnd* dst, Opnd* src1, Opnd* src2) {
return makeInst(Op_Sub, mod, dst->getType()->tag, dst, src1, src2);
}
Inst*
InstFactory::makeMul(Modifier mod, Opnd* dst, Opnd* src1, Opnd* src2) {
return makeInst(Op_Mul, mod, dst->getType()->tag, dst, src1, src2);
}
Inst*
InstFactory::makeTauDiv(Modifier mod, Opnd* dst, Opnd* src1, Opnd* src2, Opnd *tauOpndsChecked) {
assert(tauOpndsChecked->getType()->tag == Type::Tau);
return makeMultiSrcInst(Op_TauDiv, mod, dst->getType()->tag, dst, src1, src2, tauOpndsChecked);
}
Inst*
InstFactory::makeTauRem(Modifier mod, Opnd* dst, Opnd* src1, Opnd* src2, Opnd *tauOpndsChecked) {
assert(tauOpndsChecked->getType()->tag == Type::Tau);
return makeMultiSrcInst(Op_TauRem, mod, dst->getType()->tag, dst, src1, src2, tauOpndsChecked);
}
Inst*
InstFactory::makeNeg(Opnd* dst, Opnd* src) {
return makeInst(Op_Neg, Modifier(), dst->getType()->tag, dst, src);
}
Inst*
InstFactory::makeMulHi(Modifier mod, Opnd* dst, Opnd* src1, Opnd* src2) {
return makeInst(Op_MulHi, mod, dst->getType()->tag, dst, src1, src2);
}
Inst*
InstFactory::makeMin(Opnd* dst, Opnd* src1, Opnd* src2) {
return makeInst(Op_Min, Modifier(), dst->getType()->tag, dst, src1, src2);
}
Inst*
InstFactory::makeMax(Opnd* dst, Opnd* src1, Opnd* src2) {
return makeInst(Op_Max, Modifier(), dst->getType()->tag, dst, src1, src2);
}
Inst*
InstFactory::makeAbs(Opnd* dst, Opnd* src) {
return makeInst(Op_Abs, Modifier(), dst->getType()->tag, dst, src);
}
Inst* InstFactory::makeTauCheckFinite(Opnd* dst, Opnd* src) {
return makeInst(Op_TauCheckFinite, Modifier(Exception_Sometimes),
dst->getType()->tag, dst, src);
}
// Bitwise
Inst* InstFactory::makeAnd(Opnd* dst, Opnd* src1, Opnd* src2) {
return makeInst(Op_And, Modifier(), dst->getType()->tag, dst, src1, src2);
}
Inst* InstFactory::makeOr(Opnd* dst, Opnd* src1, Opnd* src2) {
return makeInst(Op_Or, Modifier(), dst->getType()->tag, dst, src1, src2);
}
Inst* InstFactory::makeXor(Opnd* dst, Opnd* src1, Opnd* src2) {
return makeInst(Op_Xor, Modifier(), dst->getType()->tag, dst, src1, src2);
}
Inst* InstFactory::makeNot(Opnd* dst, Opnd* src) {
return makeInst(Op_Not, Modifier(), dst->getType()->tag, dst, src);
}
// selection
Inst*
InstFactory::makeSelect(Opnd* dst, Opnd* src1, Opnd* src2, Opnd *src3) {
Opnd* localSrcs[3] = {src1, src2, src3};
Opnd** srcs = copyOpnds(localSrcs, 3);
return makeMultiSrcInst(Op_Select, Modifier(), dst->getType()->tag, dst,
3, srcs);
}
// conversion
Inst* InstFactory::makeConv(Modifier mod, Type::Tag toType, Opnd* dst, Opnd* src) {
//use convUnmanaged to convert between managed and unmanaged types
assert (!(dst->getType()->isUnmanagedPtr() && src->getType()->isObject())
&& !(dst->getType()->isObject() && src->getType()->isUnmanagedPtr()));
return makeInst(Op_Conv, mod, toType, dst, src);
}
Inst* InstFactory::makeConvZE(Modifier mod, Type::Tag toType, Opnd* dst, Opnd* src) {
assert((dst->getType()->isInteger() || dst->getType()->isUnmanagedPtr()) && src->getType()->isInteger());
return makeInst(Op_ConvZE, mod, toType, dst, src);
}
Inst* InstFactory::makeConvUnmanaged(Modifier mod, Type::Tag toType, Opnd* dst, Opnd* src) {
assert ((dst->getType()->isUnmanagedPtr() && (src->getType()->isObject() || src->getType()->isManagedPtr()))
|| (((dst->getType()->isObject() || dst->getType()->isManagedPtr())) && src->getType()->isUnmanagedPtr()));
return makeInst(Op_ConvUnmanaged, mod, toType, dst, src);
}
// shifts
Inst* InstFactory::makeShladd(Opnd* dst, Opnd* value, Opnd* shiftAmount, Opnd* addTo) {
Opnd* localSrcs[3] = {value, shiftAmount, addTo};
Opnd** srcs = copyOpnds(localSrcs, 3);
return makeMultiSrcInst(Op_Shladd, Modifier(), dst->getType()->tag, dst,
3, srcs);
}
Inst* InstFactory::makeShl(Modifier mod, Opnd* dst, Opnd* value, Opnd* shiftAmount) {
return makeInst(Op_Shl, mod, dst->getType()->tag, dst, value, shiftAmount);
}
Inst* InstFactory::makeShr(Modifier mod, Opnd* dst, Opnd* value, Opnd* shiftAmount) {
return makeInst(Op_Shr, mod, dst->getType()->tag, dst,
value, shiftAmount);
}
// comparison
Inst* InstFactory::makeCmp(ComparisonModifier mod, Type::Tag type, Opnd* dst, Opnd* src1, Opnd* src2) {
return makeInst(Op_Cmp, mod, type, dst, src1, src2);
}
Inst* InstFactory::makeCmp3(ComparisonModifier mod, Type::Tag type, Opnd* dst, Opnd* src1, Opnd* src2) {
return makeInst(Op_Cmp3, mod, type, dst, src1, src2);
}
Inst*
InstFactory::makeCatchLabel(U_32 labelId,
U_32 exceptionOrder,
Type* handlerExceptionType) {
return makeCatchLabelInst(labelId, exceptionOrder, handlerExceptionType);
}
CatchLabelInst*
InstFactory::makeCatchLabel(U_32 exceptionOrder,
Type* handlerExceptionType) {
return makeCatchLabelInst(createLabelNumber(), exceptionOrder, handlerExceptionType);
}
LabelInst*
InstFactory::makeLabel() {
return makeLabelInst(createLabelNumber());
}
Inst*
InstFactory::makeBranch(ComparisonModifier mod, Type::Tag type, Opnd* src1, Opnd* src2, LabelInst* labelInst) {
return makeBranchInst(Op_Branch, mod, type, src1, src2, labelInst);
;
}
Inst*
InstFactory::makeBranch(ComparisonModifier mod, Type::Tag type, Opnd* src, LabelInst* labelInst) {
return makeBranchInst(Op_Branch, mod, type, src, labelInst);
}
Inst*
InstFactory::makeJump(LabelInst* labelInst) {
return makeBranchInst(Op_Jump, labelInst);
}
Inst* InstFactory::makeJSR(LabelInst* labelInst) {
return makeBranchInst(Op_JSR, labelInst);
}
Inst* InstFactory::makeSwitch(Opnd* src, U_32 nLabels, LabelInst** labelInsts, LabelInst* defaultLabel) {
LabelInst** newLabelInsts = new (memManager) LabelInst*[nLabels];
for (U_32 i=0; i<nLabels; i++)
newLabelInsts[i] = labelInsts[i];
return makeSwitchInst(src, newLabelInsts, nLabels, defaultLabel);
}
Inst* InstFactory::makeReturn(Opnd* src) {
return makeInst(Op_Return, Modifier(), src->getType()->tag, OpndManager::getNullOpnd(), src);
}
// void return type
Inst* InstFactory::makeReturn() {
return makeInst(Op_Return, Modifier(), Type::Void, OpndManager::getNullOpnd());
}
Inst* InstFactory::makeRet(Opnd* src) {
return makeInst(Op_Ret, Modifier(), src->getType()->tag, OpndManager::getNullOpnd(), src);
}
Inst* InstFactory::makeThrow(ThrowModifier mod, Opnd* exceptionObj) {
return makeInst(Op_Throw, Modifier(mod), Type::Void, OpndManager::getNullOpnd(), exceptionObj);
}
Inst* InstFactory::makePseudoThrow() {
return makeInst(Op_PseudoThrow, Modifier(Exception_Sometimes), Type::Void, OpndManager::getNullOpnd());
}
Inst* InstFactory::makeThrowSystemException(CompilationInterface::SystemExceptionId exceptionId) {
MethodDesc* enclosingMethod = 0;
return makeTokenInst(Op_ThrowSystemException, Modifier(), Type::Void,
OpndManager::getNullOpnd(), (U_32) exceptionId, enclosingMethod);
}
Inst* InstFactory::makeThrowLinkingException(Class_Handle encClass, U_32 CPIndex, U_32 operation) {
return makeLinkingExcInst(Op_ThrowLinkingException, Modifier(), Type::Void,
OpndManager::getNullOpnd(), encClass, CPIndex, operation);
}
Inst* InstFactory::makePrefetch(Opnd* addr) {
return makeInst(Op_Prefetch, Modifier(), Type::Void, OpndManager::getNullOpnd(), addr);
}
Inst* InstFactory::makeIdentHC(Opnd* dst, Opnd* src) {
return makeInst(Op_IdentHC, Modifier(), dst->getType()->tag, dst, src);
}
Inst*
InstFactory::makeDirectCall(Opnd* dst,
Opnd* tauNullChecked,
Opnd* tauTypesChecked,
U_32 numArgs,
Opnd** args,
MethodDesc* methodDesc) {
assert(tauNullChecked->getType()->tag == Type::Tau);
assert(tauTypesChecked->getType()->tag == Type::Tau);
Type::Tag returnType = dst->isNull()? Type::Void : dst->getType()->tag;
args = copyOpnds(tauNullChecked, tauTypesChecked, args, numArgs);
return makeMethodCallInst(Op_DirectCall, Modifier(Exception_Sometimes),
returnType, dst, numArgs+2, args, methodDesc);
}
Inst*
InstFactory::makeTauVirtualCall(Opnd* dst,
Opnd *tauNullChecked,
Opnd *tauTypesChecked,
U_32 numArgs,
Opnd** args,
MethodDesc* methodDesc) {
assert(tauNullChecked->getType()->tag == Type::Tau);
assert(tauTypesChecked->getType()->tag == Type::Tau);
Type::Tag returnType = dst->isNull()? Type::Void : dst->getType()->tag;
args = copyOpnds(tauNullChecked, tauTypesChecked, args, numArgs);
return makeMethodCallInst(Op_TauVirtualCall, Modifier(Exception_Sometimes),
returnType, dst, numArgs+2, args, methodDesc);
}
Inst*
InstFactory::makeIndirectCall(Opnd* dst,
Opnd* funAddr,
Opnd* tauNullCheckedFirstArg,
Opnd* tauTypesChecked,
U_32 numArgs,
Opnd** args) {
assert(tauNullCheckedFirstArg->getType()->tag == Type::Tau);
assert(tauTypesChecked->getType()->tag == Type::Tau);
Type::Tag returnType = dst->isNull()? Type::Void : dst->getType()->tag;
Opnd** newArgs = copyOpnds(tauNullCheckedFirstArg, tauTypesChecked,
args, numArgs);
Inst* inst = makeCallInst(Op_IndirectCall, Modifier(Exception_Sometimes),
returnType, dst, funAddr, numArgs+2, newArgs);
inst->id = numInsts++;
return inst;
}
Inst*
InstFactory::makeIndirectMemoryCall(Opnd* dst,
Opnd* funAddr,
Opnd* tauNullCheckedFirstArg,
Opnd* tauTypesChecked,
U_32 numArgs,
Opnd** args) {
assert(tauNullCheckedFirstArg->getType()->tag == Type::Tau);
assert(tauTypesChecked->getType()->tag == Type::Tau);
Type::Tag returnType = dst->isNull()? Type::Void : dst->getType()->tag;
Opnd** newArgs = copyOpnds(tauNullCheckedFirstArg, tauTypesChecked,
args, numArgs);
Inst* inst = makeCallInst(Op_IndirectMemoryCall, Modifier(Exception_Sometimes),
returnType, dst, funAddr, numArgs+2, newArgs);
inst->id = numInsts++;
return inst;
}
Inst*
InstFactory::makeJitHelperCall(Opnd* dst, JitHelperCallId id,
Opnd* tauNullChecked, Opnd* tauTypesChecked,
U_32 numArgs, Opnd** args)
{
Type::Tag returnType = dst->isNull()? Type::Void : dst->getType()->tag;
if (id == ArrayCopyDirect || id == ArrayCopyReverse) // these three need taus
{
args = copyOpnds(tauNullChecked, tauTypesChecked, args, numArgs);
numArgs = numArgs+2;
} else {
args = copyOpnds(args, numArgs);
}
Modifier mod;
switch(id) {
case StringCompareTo:
case StringIndexOf:
case StringRegionMatches:
mod = Modifier(Exception_Never);
break;
default:
mod = Modifier(Exception_Sometimes);
}
return makeJitHelperCallInst(Op_JitHelperCall, mod, returnType, dst, numArgs, args, id);
}
Inst*
InstFactory::makeVMHelperCall(Opnd* dst, VM_RT_SUPPORT id, U_32 numArgs, Opnd** args) {
Type::Tag returnType = dst->isNull()? Type::Void : dst->getType()->tag;
args = copyOpnds(args, numArgs);
return makeVMHelperCallInst(Op_VMHelperCall, Modifier(Exception_Sometimes), returnType, dst, numArgs, args, id);
}
// load, store, & move
Inst*
InstFactory::makePhi(Opnd* dst, U_32 numOpnds, Opnd** opnds) {
#ifdef BRM_CHECK_TYPES
for (U_32 i=0; i<numOpnds; ++i) {
assert(opnds[i]->getType() == dst->getType());
}
#endif
Opnd** newOpnds = copyOpnds(opnds, numOpnds);
return makePhiInst(dst->getType()->tag, dst, numOpnds, newOpnds);
}
Inst*
InstFactory::makeTauPi(Opnd* dst, Opnd* src, Opnd *tauDep, PiCondition *cond) {
#ifdef BRM_CHECK_TYPES
assert(src->getType() == dst->getType());
#endif
assert(tauDep->getType()->tag == Type::Tau);
Type::Tag atype = src->getType()->tag;
TauPiInst* inst = new (memManager) TauPiInst(atype, dst, src, tauDep, cond);
inst->id = numInsts++;
return inst;
}
Inst*
InstFactory::makeCopy(Opnd* dst, Opnd* src) {
return makeInst(Op_Copy, Modifier(), dst->getType()->tag, dst, src);
}
Inst*
InstFactory::makeDefArg(Modifier mod, Opnd* arg) {
return makeInst(Op_DefArg, mod, arg->getType()->tag, arg);
}
Inst* InstFactory::makeCatch(Opnd* dst) {
return makeInst(Op_Catch, Modifier(), dst->getType()->tag, dst);
}
Inst* InstFactory::makeSaveRet(Opnd* dst) {
return makeInst(Op_SaveRet, Modifier(), dst->getType()->tag, dst);
}
Inst* InstFactory::makeLdStatic(Modifier mod, Type* type, Opnd* dst, FieldDesc* fieldDesc) {
return makeFieldAccessInst(Op_LdStatic, mod, type->tag, dst, fieldDesc);
}
Inst* InstFactory::makeTauLdField(Modifier mod, Type* type, Opnd* dst, Opnd* base,
Opnd* tauNonNullBase, Opnd *tauObjectTypeChecked,
FieldDesc* fieldDesc) {
assert(tauNonNullBase->getType()->tag == Type::Tau);
assert(tauObjectTypeChecked->getType()->tag == Type::Tau);
Opnd* localSrcs[3] = {base, tauNonNullBase, tauObjectTypeChecked};
Opnd** srcs = copyOpnds(localSrcs, 3);
return makeFieldAccessInst(Op_TauLdField, mod, type->tag, dst, 3,
srcs, fieldDesc);
}
Inst* InstFactory::makeTauLdInd(Modifier mod, Type::Tag type, Opnd* dst, Opnd* ptr,
Opnd *tauBaseNonNull, Opnd *tauAddressInRange) {
assert(tauBaseNonNull->getType()->tag == Type::Tau);
Modifier m1 = mod;
if (mod.getSpeculativeModifier() == 0) {
m1 = mod | Speculative_No;
}
return makeMultiSrcInst(Op_TauLdInd, m1, type, dst, ptr, tauBaseNonNull, tauAddressInRange);
}
Inst* InstFactory::makeTauLdElem(Modifier mod, Type* type, Opnd* dst, Opnd* array, Opnd* index,
Opnd *tauBaseNonNull, Opnd *tauAddressInRange) {
assert(tauBaseNonNull->getType()->tag == Type::Tau);
assert(tauAddressInRange->getType()->tag == Type::Tau);
return makeTypeInst(Op_TauLdElem, mod, dst->getType()->tag, dst, array,
index,
tauBaseNonNull, tauAddressInRange, type);
}
#ifdef BRM_CHECK_TYPES
static void doBRMCheck(Opnd* src, Opnd* dst) {
Type *srcType = src->getType();
Type *dstType = dst->getType();
assert((srcType == dstType) || (srcType->isNullObject() && dstType->isObject())
|| (srcType->isObject() && dstType->isObject()
&& (srcType->isUnresolvedType() || dstType->isUnresolvedType()
|| srcType->asObjectType()->isSubClassOf(dstType->asObjectType()))));
}
#endif
Inst* InstFactory::makeLdVar(Opnd* dst, VarOpnd* var) {
#ifdef BRM_CHECK_TYPES
doBRMCheck(var, dst);
#endif
return makeVarAccessInst(Op_LdVar, dst->getType()->tag, dst, var);
}
Inst* InstFactory::makeLdVar(Opnd* dst, SsaVarOpnd* var) {
#ifdef BRM_CHECK_TYPES
doBRMCheck(var, dst);
#endif
return makeVarAccessInst(Op_LdVar, dst->getType()->tag, dst, var);
}
Inst* InstFactory::makeLdStaticAddr(Opnd* dst, FieldDesc* fieldDesc) {
return makeFieldAccessInst(Op_LdStaticAddr, Modifier(), dst->getType()->tag, dst, fieldDesc);
}
Inst* InstFactory::makeLdFieldAddr(Opnd* dst, Opnd* base, FieldDesc* fieldDesc) {
return makeFieldAccessInst(Op_LdFieldAddr, Modifier(), dst->getType()->tag, dst, base, fieldDesc);
}
Inst* InstFactory::makeLdElemAddr(Type* type, Opnd* dst, Opnd* array, Opnd* index) {
return makeTypeInst(Op_LdElemAddr, Modifier(), dst->getType()->tag, dst, array, index, type);
}
Inst* InstFactory::makeLdVarAddr(Opnd* dst, VarOpnd* var) {
return makeVarAccessInst(Op_LdVarAddr, dst->getType()->tag, dst, var);
}
Inst* InstFactory::makeLdFunAddr(Opnd* dst, MethodDesc* methodDesc) {
return makeMethodInst(Op_LdFunAddr, Modifier(), dst->getType()->tag, dst, methodDesc);
}
Inst* InstFactory::makeTauLdVirtFunAddr(Opnd* dst, Opnd* vtable,
Opnd* tauVtableHasMethod,
MethodDesc* methodDesc) {
assert(tauVtableHasMethod->getType()->tag == Type::Tau);
return makeMethodInst(Op_TauLdVirtFunAddr, Modifier(), dst->getType()->tag, dst,
vtable, tauVtableHasMethod, methodDesc);
}
Inst* InstFactory::makeLdFunAddrSlot(Opnd* dst, MethodDesc* methodDesc) {
return makeMethodInst(Op_LdFunAddrSlot, Modifier(), dst->getType()->tag, dst, methodDesc);
}
Inst* InstFactory::makeTauLdVirtFunAddrSlot(Opnd* dst, Opnd* vtable, Opnd *tauVtableHasMethod,
MethodDesc* methodDesc) {
assert(tauVtableHasMethod->getType()->tag == Type::Tau);
return makeMethodInst(Op_TauLdVirtFunAddrSlot, Modifier(), dst->getType()->tag, dst, vtable,
tauVtableHasMethod, methodDesc);
}
Inst* InstFactory::makeTauLdIntfcVTableAddr(Opnd* dst, Opnd* base,
Type* vtableType) {
return makeTypeInst(Op_TauLdIntfcVTableAddr, Modifier(), dst->getType()->tag, dst, base,
vtableType);
}
Inst* InstFactory::makeTauLdVTableAddr(Opnd* dst, Opnd* base,
Opnd *tauBaseNonNull) {
assert(tauBaseNonNull);
return makeInst(Op_TauLdVTableAddr, Modifier(), dst->getType()->tag, dst, base,
tauBaseNonNull);
}
Inst* InstFactory::makeGetVTableAddr(Opnd* dst, ObjectType *type) {
return makeTypeInst(Op_GetVTableAddr, Modifier(), dst->getType()->tag, dst, type);
}
Inst* InstFactory::makeGetClassObj(Opnd* dst, ObjectType *type) {
//makeTypeInst(Op_TypeMonitorEnter, Modifier(), Type::Void, OpndManager::getNullOpnd(), type);
return makeTypeInst(Op_GetClassObj, Modifier(), dst->getType()->tag, dst, type);
}
Inst* InstFactory::makeTauArrayLen(Opnd* dst, Type::Tag type, Opnd* base,
Opnd *tauBaseIsNonNull,
Opnd *tauBaseIsArray) {
assert(tauBaseIsNonNull->getType()->tag == Type::Tau);
assert(tauBaseIsArray->getType()->tag == Type::Tau);
return makeMultiSrcInst(Op_TauArrayLen, Modifier(), type, dst, base, tauBaseIsNonNull,
tauBaseIsArray);
}
Inst* InstFactory::makeLdArrayBaseAddr(Type* type, Opnd* dst, Opnd* array) {
return makeTypeInst(Op_LdArrayBaseAddr, Modifier(), dst->getType()->tag, dst, array, type);
}
//
Inst* InstFactory::makeAddScaledIndex(Opnd* dst, Opnd* ptr, Opnd* index) {
return makeInst(Op_AddScaledIndex, Modifier(), dst->getType()->tag,
dst, ptr, index);
}
//
Inst* InstFactory::makeUncompressRef(Opnd* dst, Opnd* compref)
{
return makeInst(Op_UncompressRef, Modifier(), dst->getType()->tag,
dst, compref);
}
Inst* InstFactory::makeCompressRef(Opnd* dst, Opnd* uncompref)
{
return makeInst(Op_CompressRef, Modifier(), dst->getType()->tag,
dst, uncompref);
}
Inst* InstFactory::makeLdFieldOffset(Opnd* dst, FieldDesc *fieldDesc)
{
return makeFieldAccessInst(Op_LdFieldOffset, Modifier(),
Type::Offset, dst, fieldDesc);
}
Inst* InstFactory::makeLdFieldOffsetPlusHeapbase(Opnd* dst, FieldDesc *fieldDesc)
{
return makeFieldAccessInst(Op_LdFieldOffsetPlusHeapbase, Modifier(),
Type::OffsetPlusHeapbase, dst, fieldDesc);
}
Inst* InstFactory::makeLdArrayBaseOffset(Opnd* dst, Type *elemType)
{
return makeTypeInst(Op_LdArrayBaseOffset, Modifier(), Type::Offset, dst,
elemType);
}
Inst* InstFactory::makeLdArrayBaseOffsetPlusHeapbase(Opnd* dst, Type *elemType)
{
return makeTypeInst(Op_LdArrayBaseOffsetPlusHeapbase, Modifier(), Type::Offset, dst,
elemType);
}
Inst* InstFactory::makeLdArrayLenOffset(Opnd* dst, Type *elemType)
{
return makeTypeInst(Op_LdArrayLenOffset, Modifier(), Type::Offset, dst,
elemType);
}
Inst* InstFactory::makeLdArrayLenOffsetPlusHeapbase(Opnd* dst, Type *elemType)
{
return makeTypeInst(Op_LdArrayLenOffsetPlusHeapbase, Modifier(), Type::Offset, dst,
elemType);
}
Inst* InstFactory::makeAddOffset(Opnd* dst, Opnd* ref, Opnd* offset)
{
return makeInst(Op_AddOffset, Modifier(), dst->getType()->tag,
dst, ref, offset);
}
Inst* InstFactory::makeAddOffsetPlusHeapbase(Opnd* dst, Opnd* ref, Opnd* offset)
{
return makeInst(Op_AddOffsetPlusHeapbase, Modifier(), dst->getType()->tag,
dst, ref, offset);
}
Inst* InstFactory::makeTauStStatic(Modifier mod, Type::Tag type, Opnd* src,
Opnd *tauFieldTypeChecked, FieldDesc* fieldDesc) {
assert(tauFieldTypeChecked->getType()->tag == Type::Tau);
return makeFieldAccessInst(Op_TauStStatic, mod,
type, OpndManager::getNullOpnd(), src,
tauFieldTypeChecked, fieldDesc);
}
Inst* InstFactory::makeTauStField(Modifier mod, Type::Tag type, Opnd* src, Opnd* base,
Opnd *tauBaseNonNull, Opnd *tauAddressInRange,
Opnd *tauFieldTypeChecked,
FieldDesc* fieldDesc) {
assert(tauBaseNonNull->getType()->tag == Type::Tau);
assert(tauAddressInRange->getType()->tag == Type::Tau);
assert(tauFieldTypeChecked->getType()->tag == Type::Tau);
Opnd* localSrcs[4] = {src, base, tauBaseNonNull, tauAddressInRange};
Opnd** srcs = copyOpnds(localSrcs, 4);
return makeFieldAccessInst(Op_TauStField, mod, type, OpndManager::getNullOpnd(), 4, srcs,
fieldDesc);
}
Inst* InstFactory::makeTauStInd(Modifier mod, Type::Tag type, Opnd* src, Opnd* ptr,
Opnd *tauBaseNonNull, Opnd *tauAddressInRange, Opnd *tauElemTypeChecked) {
assert(tauBaseNonNull->getType()->tag == Type::Tau);
assert(tauAddressInRange->getType()->tag == Type::Tau);
assert(tauElemTypeChecked->getType()->tag == Type::Tau);
Opnd* localSrcs[5] = {src, ptr, tauBaseNonNull, tauAddressInRange, tauElemTypeChecked};
Opnd** srcs = copyOpnds(localSrcs, 5);
return makeMultiSrcInst(Op_TauStInd, mod, type, OpndManager::getNullOpnd(), 5, srcs);
}
Inst* InstFactory::makeTauStRef(Modifier mod, Type::Tag type, Opnd *src, Opnd* pointer,
Opnd* objbase,
Opnd *tauBaseNonNull, Opnd *tauAddressInRange,
Opnd* tauElemTypeChecked) {
assert(tauBaseNonNull->getType()->tag == Type::Tau);
assert(tauAddressInRange->getType()->tag == Type::Tau);
assert(tauElemTypeChecked->getType()->tag == Type::Tau);
Opnd* localSrcs[6] = {src, pointer, objbase,
tauBaseNonNull, tauAddressInRange, tauElemTypeChecked};
Opnd** srcs = copyOpnds(localSrcs, 6);
return makeMultiSrcInst(Op_TauStRef, mod, type, OpndManager::getNullOpnd(), 6, srcs);
}
Inst* InstFactory::makeTauStElem(Modifier mod, Type::Tag type, Opnd* src,
Opnd* array, Opnd* index,
Opnd *tauBaseNonNull, Opnd *tauAddressInRange,
Opnd *tauElemTypeChecked) {
assert(tauBaseNonNull->getType()->tag == Type::Tau);
assert(tauAddressInRange->getType()->tag == Type::Tau);
assert(tauElemTypeChecked->getType()->tag == Type::Tau);
Opnd* localSrcs[6] = {src, array, index, tauBaseNonNull, tauAddressInRange, tauElemTypeChecked};
Opnd** srcs = copyOpnds(localSrcs, 6);
return makeMultiSrcInst(Op_TauStElem, mod, type, OpndManager::getNullOpnd(), 6, srcs);
}
Inst* InstFactory::makeStVar(VarOpnd* var, Opnd* src) {
#ifdef BRM_CHECK_TYPES
doBRMCheck(src, var);
#endif
return makeVarAccessInst(Op_StVar, src->getType()->tag, var, src);
}
Inst* InstFactory::makeStVar(SsaVarOpnd* var, Opnd* src) {
#ifdef BRM_CHECK_TYPES
doBRMCheck(src, var);
#endif
return makeVarAccessInst(Op_StVar, src->getType()->tag, var, src);
}
Inst* InstFactory::makeNewObj(Opnd* dst, Type* type) {
return makeTypeInst(Op_NewObj, Modifier(Exception_Sometimes),
type->tag, dst, type);
}
Inst* InstFactory::makeNewArray(Opnd* dst, Opnd* numElems, Type* elemType) {
return makeTypeInst(Op_NewArray, Modifier(Exception_Sometimes),
dst->getType()->tag, dst, numElems, elemType);
}
Inst*
InstFactory::makeNewMultiArray(Opnd* dst,
U_32 dimensions,
Opnd** numElems,
Type* elemType) {
Opnd** newNumElems = copyOpnds(numElems, dimensions);
return makeTypeInst(Op_NewMultiArray, Modifier(Exception_Sometimes),
dst->getType()->tag, dst, dimensions, newNumElems, elemType);
}
Inst* InstFactory::makeTauMonitorEnter(Opnd* src, Opnd *tauNonNull) {
assert(tauNonNull->getType()->tag == Type::Tau);
return makeInst(Op_TauMonitorEnter, Modifier(), Type::Void, OpndManager::getNullOpnd(), src,
tauNonNull);
}
Inst* InstFactory::makeTauMonitorExit(Opnd* src, Opnd *tauNonNull) {
assert(tauNonNull->getType()->tag == Type::Tau);
return makeInst(Op_TauMonitorExit, Modifier(Exception_Sometimes),
Type::Void, OpndManager::getNullOpnd(), src, tauNonNull);
}
Inst* InstFactory::makeTypeMonitorEnter(Type *type) {
return makeTypeInst(Op_TypeMonitorEnter, Modifier(), Type::Void, OpndManager::getNullOpnd(), type);
}
Inst* InstFactory::makeTypeMonitorExit(Type *type) {
return makeTypeInst(Op_TypeMonitorExit, Modifier(Exception_Sometimes),
Type::Void, OpndManager::getNullOpnd(), type);
}
Inst* InstFactory::makeLdLockAddr(Opnd* dst, Opnd* obj) {
return makeInst(Op_LdLockAddr, Modifier(), dst->getType()->tag, dst, obj);
}
Inst* InstFactory::makeIncRecCount(Opnd* obj, Opnd* oldLock) {
return makeInst(Op_IncRecCount, Modifier(), Type::Void, OpndManager::getNullOpnd(), obj, oldLock);
}
Inst* InstFactory::makeTauBalancedMonitorEnter(Opnd *dst, Opnd* obj, Opnd *lockAddr,
Opnd *tauNonNull) {
assert(tauNonNull->getType()->tag == Type::Tau);
Opnd* localSrcs[3] = {obj, lockAddr, tauNonNull};
Opnd** srcs = copyOpnds(localSrcs, 3);
return makeMultiSrcInst(Op_TauBalancedMonitorEnter, Modifier(), dst->getType()->tag, dst, 3, srcs);
}
Inst* InstFactory::makeBalancedMonitorExit(Opnd* obj, Opnd *lockAddr, Opnd *oldValue) {
Opnd* localSrcs[3] = {obj, lockAddr, oldValue};
Opnd** srcs = copyOpnds(localSrcs, 3);
return makeMultiSrcInst(Op_BalancedMonitorExit,
Modifier(), Type::Void,
OpndManager::getNullOpnd(), 3, srcs);
}
Inst* InstFactory::makeTauOptimisticBalancedMonitorEnter(Opnd *dst, Opnd* obj,
Opnd *lockAddr, Opnd *tauNonNull) {
assert(tauNonNull->getType()->tag == Type::Tau);
Opnd* localSrcs[3] = {obj, lockAddr, tauNonNull};
Opnd** srcs = copyOpnds(localSrcs, 3);
return makeMultiSrcInst(Op_TauOptimisticBalancedMonitorEnter,
Modifier(), dst->getType()->tag,
dst, 3, srcs);
}
Inst* InstFactory::makeOptimisticBalancedMonitorExit(Opnd* obj, Opnd *lockAddr,
Opnd *oldValue) {
Opnd* localSrcs[3] = {obj, lockAddr, oldValue};
Opnd** srcs = copyOpnds(localSrcs, 3);
return makeMultiSrcInst(Op_OptimisticBalancedMonitorExit,
Modifier(Exception_Sometimes), Type::Void,
OpndManager::getNullOpnd(), 3, srcs);
}
Inst* InstFactory::makeMonitorEnterFence(Opnd* src) {
return makeInst(Op_MonitorEnterFence, Modifier(), Type::Void, OpndManager::getNullOpnd(), src);
}
Inst* InstFactory::makeMonitorExitFence(Opnd* src) {
return makeInst(Op_MonitorExitFence, Modifier(), Type::Void, OpndManager::getNullOpnd(), src);
}
Inst* InstFactory::makeLdRef(Modifier mod, Opnd* dst, MethodDesc* enclosingMethod, U_32 token) {
return makeTokenInst(Op_LdRef, mod, dst->getType()->tag, dst, token, enclosingMethod);
}
// type checking
Inst* InstFactory::makeTauStaticCast(Opnd* dst, Opnd* src, Opnd *tauCastChecked, Type* type) {
assert(tauCastChecked->getType()->tag == Type::Tau);
return makeTypeInst(Op_TauStaticCast, Modifier(), dst->getType()->tag, dst, src,
tauCastChecked, type);
}
Inst* InstFactory::makeTauCast(Opnd* dst, Opnd* src, Opnd *tauCheckedNull, Type* type) {
assert(tauCheckedNull->getType()->tag == Type::Tau);
return makeTypeInst(Op_TauCast,
(Modifier(Exception_Sometimes)),
dst->getType()->tag, dst, src, tauCheckedNull, type);
}
Inst* InstFactory::makeTauAsType(Opnd* dst, Opnd* src, Opnd *tauNullChecked, Type* type) {
assert(tauNullChecked->getType()->tag == Type::Tau);
return makeTypeInst(Op_TauAsType, Modifier(), dst->getType()->tag, dst, src, tauNullChecked, type);
}
Inst* InstFactory::makeTauInstanceOf(Opnd* dst, Opnd* src, Opnd* tauNullChecked,
Type* type) {
assert(tauNullChecked->getType()->tag == Type::Tau);
return makeTypeInst(Op_TauInstanceOf, Modifier(), dst->getType()->tag, dst, src,
tauNullChecked, type);
}
Inst* InstFactory::makeInitType(Type* type) {
return makeTypeInst(Op_InitType, Modifier(Exception_Sometimes),
Type::Void, OpndManager::getNullOpnd(), type);
}
// lowered instructions
Inst* InstFactory::makeTauCheckBounds(Opnd *dst, Opnd* arrayLen, Opnd* index) {
return makeInst(Op_TauCheckBounds, Modifier(Exception_Sometimes)|Modifier(Overflow_Unsigned),
Type::Tau, dst, arrayLen, index);
}
Inst* InstFactory::makeTauCheckLowerBound(Opnd *dst, Opnd* lb, Opnd *idx) {
return makeInst(Op_TauCheckLowerBound,
Modifier(Exception_Sometimes)|Modifier(Overflow_Unsigned),
Type::Tau, dst, lb, idx);
}
Inst* InstFactory::makeTauCheckUpperBound(Opnd *dst, Opnd* idx, Opnd *ub) {
return makeInst(Op_TauCheckUpperBound,
Modifier(Exception_Sometimes)|Modifier(Overflow_Unsigned),
Type::Tau, dst, idx, ub);
}
Inst* InstFactory::makeTauCheckNull(Opnd* dst, Opnd* base) {
assert(dst->getType()->tag == Type::Tau);
return makeInst(Op_TauCheckNull, Modifier(Exception_Sometimes)|Modifier(DefArgNoModifier),
Type::Tau, dst, base);
}
Inst* InstFactory::makeTauCheckZero(Opnd* dst, Opnd* src) {
assert(dst->getType()->tag == Type::Tau);
return makeInst(Op_TauCheckZero, Modifier(Exception_Sometimes),
Type::Tau, dst, src);
}
Inst* InstFactory::makeTauCheckDivOpnds(Opnd *dst, Opnd* src1, Opnd* src2) {
return makeInst(Op_TauCheckDivOpnds, Modifier(Exception_Sometimes), Type::Tau,
dst, src1, src2);
}
Inst* InstFactory::makeTauCheckElemType(Opnd *dst, Opnd* array, Opnd* src,
Opnd *tauNullChecked,
Opnd *tauIsArray) {
assert(tauNullChecked->getType()->tag == Type::Tau);
assert(tauIsArray->getType()->tag == Type::Tau);
return makeMultiSrcInst(Op_TauCheckElemType, Modifier(Exception_Sometimes),
Type::Tau, dst, array, src, tauNullChecked,
tauIsArray);
}
Inst* InstFactory::makeLdConst(Opnd* dst, I_32 val) {
return makeConstInst(dst, val);
}
Inst* InstFactory::makeLdConst(Opnd* dst, int64 val) {
return makeConstInst(dst, val);
}
Inst* InstFactory::makeLdConst(Opnd* dst, float val) {
return makeConstInst(dst, val);
}
Inst* InstFactory::makeLdConst(Opnd* dst, double val) {
return makeConstInst(dst, val);
}
Inst* InstFactory::makeLdConst(Opnd* dst, ConstInst::ConstValue val) {
return makeConstInst(dst, val);
}
Inst* InstFactory::makeLdNull(Opnd* dst) {
return makeConstInst(dst);
}
Inst* InstFactory::makeIncCounter(U_32 val) {
return makeTokenInst(Op_IncCounter, Modifier(), Type::Void, OpndManager::getNullOpnd(), val, NULL);
}
Inst* InstFactory::makeTauPoint(Opnd *dst) {
assert(dst->getType()->tag == Type::Tau);
return makeInst(Op_TauPoint, Modifier(), Type::Tau, dst);
}
Inst* InstFactory::makeTauEdge(Opnd *dst) {
assert(dst->getType()->tag == Type::Tau);
return makeInst(Op_TauEdge, Modifier(), Type::Tau, dst);
}
Inst* InstFactory::makeTauAnd(Opnd *dst, U_32 numOpnds, Opnd** opnds) {
assert(dst->getType()->tag == Type::Tau);
assert(numOpnds > 0);
Opnd** srcs = copyOpnds(opnds, numOpnds);
return makeMultiSrcInst(Op_TauAnd, Modifier(), Type::Tau, dst, numOpnds, srcs);
}
Inst* InstFactory::makeTauUnsafe(Opnd *dst) {
assert(dst->getType()->tag == Type::Tau);
return makeInst(Op_TauUnsafe, Modifier(), Type::Tau, dst);
}
Inst* InstFactory::makeTauSafe(Opnd *dst) {
assert(dst->getType()->tag == Type::Tau);
return makeInst(Op_TauSafe, Modifier(), Type::Tau, dst);
}
Inst* InstFactory::makeTauCheckCast(Opnd* dst, Opnd* src, Opnd *tauCheckedNull, Type* type) {
assert(tauCheckedNull->getType()->tag == Type::Tau);
assert(dst->getType()->tag == Type::Tau);
return makeTypeInst(Op_TauCheckCast,
(Modifier(Exception_Sometimes)),
Type::Tau, dst, src, tauCheckedNull, type);
}
Inst* InstFactory::makeTauHasType(Opnd* dst, Opnd* src, Type* type) {
assert(dst->getType()->tag == Type::Tau);
return makeTypeInst(Op_TauHasType,
Modifier(),
Type::Tau, dst, src, type);
}
Inst* InstFactory::makeTauHasExactType(Opnd* dst, Opnd* src, Type* type) {
assert(dst->getType()->tag == Type::Tau);
return makeTypeInst(Op_TauHasExactType,
Modifier(),
Type::Tau, dst, src, type);
}
Inst* InstFactory::makeTauIsNonNull(Opnd* dst, Opnd* src) {
assert(dst->getType()->tag == Type::Tau);
return makeInst(Op_TauIsNonNull,
Modifier(),
Type::Tau, dst, src);
}
//-----------------------------------------------------------------------------
// InstOptimizer methods
//-----------------------------------------------------------------------------
Inst*
InstOptimizer::dispatch(Inst* inst) {
switch (inst->getOpcode()) {
case Op_Add: return caseAdd(inst);
case Op_Mul: return caseMul(inst);
case Op_Sub: return caseSub(inst);
case Op_TauDiv: return caseTauDiv(inst);
case Op_TauRem: return caseTauRem(inst);
case Op_Neg: return caseNeg(inst);
case Op_MulHi: return caseMulHi(inst);
case Op_Min: return caseMin(inst);
case Op_Max: return caseMax(inst);
case Op_Abs: return caseAbs(inst);
case Op_And: return caseAnd(inst);
case Op_Or: return caseOr(inst);
case Op_Xor: return caseXor(inst);
case Op_Not: return caseNot(inst);
case Op_Select: return caseSelect(inst);
case Op_Conv: return caseConv(inst);
case Op_ConvZE: return caseConvZE(inst);
case Op_ConvUnmanaged: return caseConvUnmanaged(inst);
case Op_Shladd: return caseShladd(inst);
case Op_Shl: return caseShl(inst);
case Op_Shr: return caseShr(inst);
case Op_Cmp: return caseCmp(inst);
case Op_Cmp3: return caseCmp3(inst);
case Op_Branch: return caseBranch(inst->asBranchInst());
case Op_Jump: return caseJump(inst->asBranchInst());
case Op_Switch: return caseSwitch(inst->asSwitchInst());
case Op_DirectCall: return caseDirectCall(inst->asMethodCallInst());
case Op_TauVirtualCall: return caseTauVirtualCall(inst->asMethodCallInst());
case Op_IndirectCall: return caseIndirectCall(inst->asCallInst());
case Op_IndirectMemoryCall: return caseIndirectMemoryCall(inst->asCallInst());
case Op_JitHelperCall: return caseJitHelperCall(inst->asJitHelperCallInst());
case Op_VMHelperCall: return caseVMHelperCall(inst->asVMHelperCallInst());
case Op_Return: return caseReturn(inst);
case Op_Catch: return caseCatch(inst);
case Op_Throw: return caseThrow(inst);
case Op_PseudoThrow: return casePseudoThrow(inst);
case Op_ThrowSystemException: return caseThrowSystemException(inst);
case Op_ThrowLinkingException: return caseThrowLinkingException(inst);
case Op_JSR: return caseJSR(inst);
case Op_Ret: return caseRet(inst);
case Op_SaveRet: return caseSaveRet(inst);
case Op_Copy: return caseCopy(inst);
case Op_DefArg: return caseDefArg(inst);
case Op_LdConstant: return caseLdConstant(inst->asConstInst());
case Op_LdRef: return caseLdRef(inst->asTokenInst());
case Op_LdVar: return caseLdVar(inst);
case Op_LdVarAddr: return caseLdVarAddr(inst);
case Op_TauLdInd: return caseTauLdInd(inst);
case Op_TauLdField: return caseTauLdField(inst->asFieldAccessInst());
case Op_LdStatic: return caseLdStatic(inst->asFieldAccessInst());
case Op_TauLdElem: return caseTauLdElem(inst->asTypeInst());
case Op_LdFieldAddr: return caseLdFieldAddr(inst->asFieldAccessInst());
case Op_LdStaticAddr: return caseLdStaticAddr(inst->asFieldAccessInst());
case Op_LdElemAddr: return caseLdElemAddr(inst->asTypeInst());
case Op_TauLdVTableAddr: return caseTauLdVTableAddr(inst);
case Op_TauLdIntfcVTableAddr: return caseTauLdIntfcVTableAddr(inst->asTypeInst());
case Op_TauLdVirtFunAddr: return caseTauLdVirtFunAddr(inst->asMethodInst());
case Op_TauLdVirtFunAddrSlot: return caseTauLdVirtFunAddrSlot(inst->asMethodInst());
case Op_LdFunAddr: return caseLdFunAddr(inst->asMethodInst());
case Op_LdFunAddrSlot: return caseLdFunAddrSlot(inst->asMethodInst());
case Op_GetVTableAddr: return caseGetVTableAddr(inst->asTypeInst());
case Op_GetClassObj: return caseGetClassObj(inst->asTypeInst());
case Op_TauArrayLen: return caseTauArrayLen(inst);
case Op_LdArrayBaseAddr: return caseLdArrayBaseAddr(inst);
case Op_AddScaledIndex: return caseAddScaledIndex(inst);
case Op_StVar: return caseStVar(inst);
case Op_TauStInd: return caseTauStInd(inst);
case Op_TauStField: return caseTauStField(inst);
case Op_TauStElem: return caseTauStElem(inst);
case Op_TauStStatic: return caseTauStStatic(inst);
case Op_TauStRef: return caseTauStRef(inst);
case Op_TauCheckBounds: return caseTauCheckBounds(inst);
case Op_TauCheckLowerBound: return caseTauCheckLowerBound(inst);
case Op_TauCheckUpperBound: return caseTauCheckUpperBound(inst);
case Op_TauCheckNull: return caseTauCheckNull(inst);
case Op_TauCheckZero: return caseTauCheckZero(inst);
case Op_TauCheckDivOpnds: return caseTauCheckDivOpnds(inst);
case Op_TauCheckElemType: return caseTauCheckElemType(inst);
case Op_TauCheckFinite: return caseTauCheckFinite(inst);
case Op_NewObj: return caseNewObj(inst);
case Op_NewArray: return caseNewArray(inst);
case Op_NewMultiArray: return caseNewMultiArray(inst);
case Op_TauMonitorEnter: return caseTauMonitorEnter(inst);
case Op_TauMonitorExit: return caseTauMonitorExit(inst);
case Op_TypeMonitorEnter: return caseTypeMonitorEnter(inst);
case Op_TypeMonitorExit: return caseTypeMonitorExit(inst);
case Op_LdLockAddr: return caseLdLockAddr(inst);
case Op_IncRecCount: return caseIncRecCount(inst);
case Op_TauBalancedMonitorEnter: return caseTauBalancedMonitorEnter(inst);
case Op_BalancedMonitorExit: return caseBalancedMonitorExit(inst);
case Op_TauOptimisticBalancedMonitorEnter: return caseTauOptimisticBalancedMonitorEnter(inst);
case Op_OptimisticBalancedMonitorExit: return caseOptimisticBalancedMonitorExit(inst);
case Op_MonitorEnterFence: return caseMonitorEnterFence(inst);
case Op_MonitorExitFence: return caseMonitorExitFence(inst);
case Op_TauStaticCast: return caseTauStaticCast(inst->asTypeInst());
case Op_TauCast: return caseTauCast(inst->asTypeInst());
case Op_TauAsType: return caseTauAsType(inst->asTypeInst());
case Op_TauInstanceOf: return caseTauInstanceOf(inst->asTypeInst());
case Op_InitType: return caseInitType(inst->asTypeInst());
case Op_Label: return caseLabel(inst);
case Op_MethodEntry: return caseMethodEntry(inst);
case Op_MethodEnd: return caseMethodEnd(inst);
case Op_Phi: return casePhi(inst);
case Op_TauPi: return caseTauPi(inst->asTauPiInst());
case Op_IncCounter: return caseIncCounter(inst);
case Op_Prefetch: return casePrefetch(inst);
case Op_UncompressRef: return caseUncompressRef(inst);
case Op_CompressRef: return caseCompressRef(inst);
case Op_LdFieldOffset: return caseLdFieldOffset(inst->asFieldAccessInst());
case Op_LdFieldOffsetPlusHeapbase: return caseLdFieldOffsetPlusHeapbase(inst->asFieldAccessInst());
case Op_LdArrayBaseOffset: return caseLdArrayBaseOffset(inst->asTypeInst());
case Op_LdArrayBaseOffsetPlusHeapbase: return caseLdArrayBaseOffsetPlusHeapbase(inst->asTypeInst());
case Op_LdArrayLenOffset: return caseLdArrayLenOffset(inst->asTypeInst());
case Op_LdArrayLenOffsetPlusHeapbase: return caseLdArrayLenOffsetPlusHeapbase(inst->asTypeInst());
case Op_AddOffset: return caseAddOffset(inst);
case Op_AddOffsetPlusHeapbase: return caseAddOffsetPlusHeapbase(inst);
case Op_TauPoint: return caseTauPoint(inst);
case Op_TauEdge: return caseTauEdge(inst);
case Op_TauAnd: return caseTauAnd(inst);
case Op_TauUnsafe: return caseTauUnsafe(inst);
case Op_TauSafe: return caseTauSafe(inst);
case Op_TauCheckCast: return caseTauCheckCast(inst->asTypeInst());
case Op_TauHasType: return caseTauHasType(inst->asTypeInst());
case Op_TauHasExactType: return caseTauHasExactType(inst->asTypeInst());
case Op_TauIsNonNull: return caseTauIsNonNull(inst);
case Op_IdentHC: return caseIdentHC(inst);
default:
::std::cerr << "Unknown opcode! " << inst->getOpcode() << " : "
<< inst->getOperation().getOpcodeString() << ::std::endl;
assert(0);
}
return NULL;
}
} //namespace Jitrino