blob: cf419b105b610fbaf0390d6ae93fea94044e2a09 [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
*
*/
#include <iostream>
#include "Opnd.h"
#include "Inst.h"
#include "IRBuilder.h"
namespace Jitrino {
NullOpnd OpndManager::_nullOpnd;
//-----------------------------------------------------------------------------
// Method for printing operands. Move to an IRPrinter file.
//-----------------------------------------------------------------------------
void Opnd::print(::std::ostream& os) const {
if (isGlobal())
os << "g";
else
os << "t";
os << (int)getId();
}
void VarOpnd::print(::std::ostream& os) const {
os << "v" << (int)getId();
}
void SsaVarOpnd::print(::std::ostream& os) const {
var->print(os);
os << "." << (int)getId();
}
void PiOpnd::print(::std::ostream& os) const {
orgOpnd->print(os);
os << "." << (int)getId();
}
void OpndBase::printWithType(::std::ostream& os) const {
print(os);
os << ":";
getType()->print(os);
}
void VarOpnd::printWithType(::std::ostream& os) const {
Opnd::printWithType(os);
if (isPinnedFlag == true)
os << " PINNED";
}
void SsaVarOpnd::printWithType(::std::ostream& os) const {
print(os);
os << ":";
getType()->print(os);
}
void VarOpnd::addVarAccessInst(VarAccessInst* varInst) {
if (varInst->isStVar())
numStores++;
else
numLoads++;
varAccessInsts = varInst;
}
void OpndManager::deleteVar(VarOpnd *var) {
// delete all instructions that ld/st this var
VarAccessInst* inst = var->varAccessInsts;
while (inst != NULL) {
VarOpnd *instVar = inst->getBaseVar();
if (!instVar || (instVar == var)) {
if (Log::isEnabled()) {
Log::out() << "Removing inst ";
inst->print(Log::out());
Log::out() << " for deleted var ";
var->print(Log::out());
Log::out() << ::std::endl;
}
inst->unlink();
} else {
if (Log::isEnabled()) {
Log::out() << "Found misfiled varAccessInst ";
inst->print(Log::out());
Log::out() << " for deleted var ";
var->print(Log::out());
Log::out() << ::std::endl;
}
instVar->addVarAccessInst(inst);
if (instVar->isDeadFlag) {
// looks already deleted;
inst->unlink();
if (Log::isEnabled()) {
Log::out() << "Correct var looks already deleted, so removing inst anyway."
<< ::std::endl;
}
} else {
// don't delete it
}
}
inst = inst->getNextVarAccessInst();
}
var->isDeadFlag = true;
if (var == varOpnds) {
if (var == var->nextVarInMethod) {
varOpnds = 0;
} else {
varOpnds = var->nextVarInMethod;
}
}
var->nextVarInMethod->prevVarInMethod = var->prevVarInMethod;
var->prevVarInMethod->nextVarInMethod = var->nextVarInMethod;
}
Type*
OpndManager::getOpndTypeFromLdType(Type* ldType) {
switch (ldType->tag) {
case Type::Boolean: case Type::Char:
case Type::Int8: case Type::Int16: case Type::Int32:
case Type::UInt8: case Type::UInt16: case Type::UInt32:
return typeManager.getInt32Type();
case Type::IntPtr: case Type::UIntPtr:
return ldType;
//return typeManager.getIntPtrType();
case Type::Int64: case Type::UInt64:
return typeManager.getInt64Type();
case Type::Single:
return typeManager.getSingleType();
case Type::Double:
return typeManager.getDoubleType();
case Type::Float:
return typeManager.getFloatType();
// object types
case Type::CompressedSystemObject:
case Type::CompressedUnresolvedObject:
case Type::CompressedSystemClass:
case Type::CompressedSystemString:
case Type::CompressedArray: case Type::CompressedObject:
case Type::CompressedNullObject:
case Type::SystemObject: case Type::SystemClass: case Type::SystemString:
case Type::Array: case Type::Object:
case Type::UnresolvedObject:
case Type::NullObject:
case Type::Offset: case Type::OffsetPlusHeapbase:
case Type::VTablePtr:
case Type::Tau:
return ldType;
// value and pointer types
case Type::Value:
if (ldType->isEnum()) {
return getOpndTypeFromLdType(((EnumType*)ldType)->getUnderlyingType());
}
return ldType;
case Type::UnmanagedPtr:
//return typeManager.getIntPtrType();
case Type::ManagedPtr: // Managed ptr is valid only for ldvar or ldarg
case Type::TypedReference: // TypedReference is valid only for ldvar or ldarg
return ldType;
// function pointers
case Type::MethodPtr:
return ldType;
case Type::Void:
return typeManager.getVoidType(); // happens only for calls
case Type::VTablePtrObj:
case Type::ITablePtrObj:
case Type::ArrayElementType:
return ldType;
default:
assert(0); // missed something
}
return typeManager.getVoidType(); // get rid of compiler warning message
}
Opnd*
OpndRenameTable::duplicate(OpndManager& opndManager, Opnd* opndToRename) {
if (opndToRename->isSsaTmpOpnd()) {
Opnd *newOpnd = opndManager.createSsaTmpOpnd(opndToRename->getType());
// record the correspondence between the new operand and the old operand
setMapping(opndToRename,newOpnd);
return newOpnd;
} else if (opndToRename->isSsaOpnd()) {
if (!renameSsaOpnd) {
assert(0);
} else {
VarOpnd* var = ((SsaVarOpnd*)opndToRename)->getVar();
Opnd *newOpnd = opndManager.createSsaVarOpnd(var);
setMapping(opndToRename,newOpnd);
return newOpnd;
}
} else {
}
return opndToRename;
}
} //namespace Jitrino