1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

Eliminate all remaining tabs and trailing spaces.

llvm-svn: 22523
This commit is contained in:
Jeff Cohen 2005-07-27 06:12:32 +00:00
parent 54792213a7
commit bd51ec7461
67 changed files with 1253 additions and 1253 deletions

View File

@ -9,7 +9,7 @@
// //
// Parallel JIT // Parallel JIT
// //
// This test program creates two LLVM functions then calls them from three // This test program creates two LLVM functions then calls them from three
// separate threads. It requires the pthreads library. // separate threads. It requires the pthreads library.
// The three threads are created and then block waiting on a condition variable. // The three threads are created and then block waiting on a condition variable.
// Once all threads are blocked on the conditional variable, the main thread // Once all threads are blocked on the conditional variable, the main thread
@ -28,32 +28,32 @@
#include <iostream> #include <iostream>
using namespace llvm; using namespace llvm;
static Function* createAdd1( Module* M ) static Function* createAdd1(Module* M)
{ {
// Create the add1 function entry and insert this entry into module M. The // Create the add1 function entry and insert this entry into module M. The
// function will have a return type of "int" and take an argument of "int". // function will have a return type of "int" and take an argument of "int".
// The '0' terminates the list of argument types. // The '0' terminates the list of argument types.
Function *Add1F = M->getOrInsertFunction("add1", Type::IntTy, Type::IntTy, 0); Function *Add1F = M->getOrInsertFunction("add1", Type::IntTy, Type::IntTy, 0);
// Add a basic block to the function. As before, it automatically inserts // Add a basic block to the function. As before, it automatically inserts
// because of the last argument. // because of the last argument.
BasicBlock *BB = new BasicBlock("EntryBlock", Add1F); BasicBlock *BB = new BasicBlock("EntryBlock", Add1F);
// Get pointers to the constant `1'. // Get pointers to the constant `1'.
Value *One = ConstantSInt::get(Type::IntTy, 1); Value *One = ConstantSInt::get(Type::IntTy, 1);
// Get pointers to the integer argument of the add1 function... // Get pointers to the integer argument of the add1 function...
assert(Add1F->arg_begin() != Add1F->arg_end()); // Make sure there's an arg assert(Add1F->arg_begin() != Add1F->arg_end()); // Make sure there's an arg
Argument *ArgX = Add1F->arg_begin(); // Get the arg Argument *ArgX = Add1F->arg_begin(); // Get the arg
ArgX->setName("AnArg"); // Give it a nice symbolic name for fun. ArgX->setName("AnArg"); // Give it a nice symbolic name for fun.
// Create the add instruction, inserting it into the end of BB. // Create the add instruction, inserting it into the end of BB.
Instruction *Add = BinaryOperator::createAdd(One, ArgX, "addresult", BB); Instruction *Add = BinaryOperator::createAdd(One, ArgX, "addresult", BB);
// Create the return instruction and add it to the basic block // Create the return instruction and add it to the basic block
new ReturnInst(Add, BB); new ReturnInst(Add, BB);
// Now, function add1 is ready. // Now, function add1 is ready.
return Add1F; return Add1F;
} }
@ -62,45 +62,45 @@ static Function *CreateFibFunction(Module *M)
// Create the fib function and insert it into module M. This function is said // Create the fib function and insert it into module M. This function is said
// to return an int and take an int parameter. // to return an int and take an int parameter.
Function *FibF = M->getOrInsertFunction("fib", Type::IntTy, Type::IntTy, 0); Function *FibF = M->getOrInsertFunction("fib", Type::IntTy, Type::IntTy, 0);
// Add a basic block to the function. // Add a basic block to the function.
BasicBlock *BB = new BasicBlock("EntryBlock", FibF); BasicBlock *BB = new BasicBlock("EntryBlock", FibF);
// Get pointers to the constants. // Get pointers to the constants.
Value *One = ConstantSInt::get(Type::IntTy, 1); Value *One = ConstantSInt::get(Type::IntTy, 1);
Value *Two = ConstantSInt::get(Type::IntTy, 2); Value *Two = ConstantSInt::get(Type::IntTy, 2);
// Get pointer to the integer argument of the add1 function... // Get pointer to the integer argument of the add1 function...
Argument *ArgX = FibF->arg_begin(); // Get the arg. Argument *ArgX = FibF->arg_begin(); // Get the arg.
ArgX->setName("AnArg"); // Give it a nice symbolic name for fun. ArgX->setName("AnArg"); // Give it a nice symbolic name for fun.
// Create the true_block. // Create the true_block.
BasicBlock *RetBB = new BasicBlock("return", FibF); BasicBlock *RetBB = new BasicBlock("return", FibF);
// Create an exit block. // Create an exit block.
BasicBlock* RecurseBB = new BasicBlock("recurse", FibF); BasicBlock* RecurseBB = new BasicBlock("recurse", FibF);
// Create the "if (arg < 2) goto exitbb" // Create the "if (arg < 2) goto exitbb"
Value *CondInst = BinaryOperator::createSetLE(ArgX, Two, "cond", BB); Value *CondInst = BinaryOperator::createSetLE(ArgX, Two, "cond", BB);
new BranchInst(RetBB, RecurseBB, CondInst, BB); new BranchInst(RetBB, RecurseBB, CondInst, BB);
// Create: ret int 1 // Create: ret int 1
new ReturnInst(One, RetBB); new ReturnInst(One, RetBB);
// create fib(x-1) // create fib(x-1)
Value *Sub = BinaryOperator::createSub(ArgX, One, "arg", RecurseBB); Value *Sub = BinaryOperator::createSub(ArgX, One, "arg", RecurseBB);
Value *CallFibX1 = new CallInst(FibF, Sub, "fibx1", RecurseBB); Value *CallFibX1 = new CallInst(FibF, Sub, "fibx1", RecurseBB);
// create fib(x-2) // create fib(x-2)
Sub = BinaryOperator::createSub(ArgX, Two, "arg", RecurseBB); Sub = BinaryOperator::createSub(ArgX, Two, "arg", RecurseBB);
Value *CallFibX2 = new CallInst(FibF, Sub, "fibx2", RecurseBB); Value *CallFibX2 = new CallInst(FibF, Sub, "fibx2", RecurseBB);
// fib(x-1)+fib(x-2) // fib(x-1)+fib(x-2)
Value *Sum = Value *Sum =
BinaryOperator::createAdd(CallFibX1, CallFibX2, "addresult", RecurseBB); BinaryOperator::createAdd(CallFibX1, CallFibX2, "addresult", RecurseBB);
// Create the return instruction and add it to the basic block // Create the return instruction and add it to the basic block
new ReturnInst(Sum, RecurseBB); new ReturnInst(Sum, RecurseBB);
return FibF; return FibF;
} }
@ -120,23 +120,23 @@ public:
{ {
n = 0; n = 0;
waitFor = 0; waitFor = 0;
int result = pthread_cond_init( &condition, NULL ); int result = pthread_cond_init( &condition, NULL );
assert( result == 0 ); assert( result == 0 );
result = pthread_mutex_init( &mutex, NULL ); result = pthread_mutex_init( &mutex, NULL );
assert( result == 0 ); assert( result == 0 );
} }
~WaitForThreads() ~WaitForThreads()
{ {
int result = pthread_cond_destroy( &condition ); int result = pthread_cond_destroy( &condition );
assert( result == 0 ); assert( result == 0 );
result = pthread_mutex_destroy( &mutex ); result = pthread_mutex_destroy( &mutex );
assert( result == 0 ); assert( result == 0 );
} }
// All threads will stop here until another thread calls releaseThreads // All threads will stop here until another thread calls releaseThreads
void block() void block()
{ {
@ -144,26 +144,26 @@ public:
assert( result == 0 ); assert( result == 0 );
n ++; n ++;
//~ std::cout << "block() n " << n << " waitFor " << waitFor << std::endl; //~ std::cout << "block() n " << n << " waitFor " << waitFor << std::endl;
assert( waitFor == 0 || n <= waitFor ); assert( waitFor == 0 || n <= waitFor );
if ( waitFor > 0 && n == waitFor ) if ( waitFor > 0 && n == waitFor )
{ {
// There are enough threads blocked that we can release all of them // There are enough threads blocked that we can release all of them
std::cout << "Unblocking threads from block()" << std::endl; std::cout << "Unblocking threads from block()" << std::endl;
unblockThreads(); unblockThreads();
} }
else else
{ {
// We just need to wait until someone unblocks us // We just need to wait until someone unblocks us
result = pthread_cond_wait( &condition, &mutex ); result = pthread_cond_wait( &condition, &mutex );
assert( result == 0 ); assert( result == 0 );
} }
// unlock the mutex before returning // unlock the mutex before returning
result = pthread_mutex_unlock( &mutex ); result = pthread_mutex_unlock( &mutex );
assert( result == 0 ); assert( result == 0 );
} }
// If there are num or more threads blocked, it will signal them all // If there are num or more threads blocked, it will signal them all
// Otherwise, this thread blocks until there are enough OTHER threads // Otherwise, this thread blocks until there are enough OTHER threads
// blocked // blocked
@ -171,22 +171,22 @@ public:
{ {
int result = pthread_mutex_lock( &mutex ); int result = pthread_mutex_lock( &mutex );
assert( result == 0 ); assert( result == 0 );
if ( n >= num ) { if ( n >= num ) {
std::cout << "Unblocking threads from releaseThreads()" << std::endl; std::cout << "Unblocking threads from releaseThreads()" << std::endl;
unblockThreads(); unblockThreads();
} }
else else
{ {
waitFor = num; waitFor = num;
pthread_cond_wait( &condition, &mutex ); pthread_cond_wait( &condition, &mutex );
} }
// unlock the mutex before returning // unlock the mutex before returning
result = pthread_mutex_unlock( &mutex ); result = pthread_mutex_unlock( &mutex );
assert( result == 0 ); assert( result == 0 );
} }
private: private:
void unblockThreads() void unblockThreads()
{ {
@ -194,7 +194,7 @@ private:
// enter while threads are exiting, they will block instead // enter while threads are exiting, they will block instead
// of triggering a new release of threads // of triggering a new release of threads
n = 0; n = 0;
// Reset waitFor to zero: this way, if waitFor threads enter // Reset waitFor to zero: this way, if waitFor threads enter
// while threads are exiting, they will block instead of // while threads are exiting, they will block instead of
// triggering a new release of threads // triggering a new release of threads
@ -203,7 +203,7 @@ private:
int result = pthread_cond_broadcast( &condition ); int result = pthread_cond_broadcast( &condition );
assert( result == 0 ); assert( result == 0 );
} }
size_t n; size_t n;
size_t waitFor; size_t waitFor;
pthread_cond_t condition; pthread_cond_t condition;
@ -215,60 +215,60 @@ static WaitForThreads synchronize;
void* callFunc( void* param ) void* callFunc( void* param )
{ {
struct threadParams* p = (struct threadParams*) param; struct threadParams* p = (struct threadParams*) param;
// Call the `foo' function with no arguments: // Call the `foo' function with no arguments:
std::vector<GenericValue> Args(1); std::vector<GenericValue> Args(1);
Args[0].IntVal = p->value; Args[0].IntVal = p->value;
synchronize.block(); // wait until other threads are at this point synchronize.block(); // wait until other threads are at this point
GenericValue gv = p->EE->runFunction(p->F, Args); GenericValue gv = p->EE->runFunction(p->F, Args);
return (void*) intptr_t(gv.IntVal); return (void*) intptr_t(gv.IntVal);
} }
int main() int main()
{ {
// Create some module to put our function into it. // Create some module to put our function into it.
Module *M = new Module("test"); Module *M = new Module("test");
Function* add1F = createAdd1( M ); Function* add1F = createAdd1( M );
Function* fibF = CreateFibFunction( M ); Function* fibF = CreateFibFunction( M );
// Now we create the JIT. // Now we create the JIT.
ExistingModuleProvider* MP = new ExistingModuleProvider(M); ExistingModuleProvider* MP = new ExistingModuleProvider(M);
ExecutionEngine* EE = ExecutionEngine::create(MP, false); ExecutionEngine* EE = ExecutionEngine::create(MP, false);
//~ std::cout << "We just constructed this LLVM module:\n\n" << *M; //~ std::cout << "We just constructed this LLVM module:\n\n" << *M;
//~ std::cout << "\n\nRunning foo: " << std::flush; //~ std::cout << "\n\nRunning foo: " << std::flush;
// Create one thread for add1 and two threads for fib // Create one thread for add1 and two threads for fib
struct threadParams add1 = { EE, add1F, 1000 }; struct threadParams add1 = { EE, add1F, 1000 };
struct threadParams fib1 = { EE, fibF, 39 }; struct threadParams fib1 = { EE, fibF, 39 };
struct threadParams fib2 = { EE, fibF, 42 }; struct threadParams fib2 = { EE, fibF, 42 };
pthread_t add1Thread; pthread_t add1Thread;
int result = pthread_create( &add1Thread, NULL, callFunc, &add1 ); int result = pthread_create( &add1Thread, NULL, callFunc, &add1 );
if ( result != 0 ) { if ( result != 0 ) {
std::cerr << "Could not create thread" << std::endl; std::cerr << "Could not create thread" << std::endl;
return 1; return 1;
} }
pthread_t fibThread1; pthread_t fibThread1;
result = pthread_create( &fibThread1, NULL, callFunc, &fib1 ); result = pthread_create( &fibThread1, NULL, callFunc, &fib1 );
if ( result != 0 ) { if ( result != 0 ) {
std::cerr << "Could not create thread" << std::endl; std::cerr << "Could not create thread" << std::endl;
return 1; return 1;
} }
pthread_t fibThread2; pthread_t fibThread2;
result = pthread_create( &fibThread2, NULL, callFunc, &fib2 ); result = pthread_create( &fibThread2, NULL, callFunc, &fib2 );
if ( result != 0 ) { if ( result != 0 ) {
std::cerr << "Could not create thread" << std::endl; std::cerr << "Could not create thread" << std::endl;
return 1; return 1;
} }
synchronize.releaseThreads(3); // wait until other threads are at this point synchronize.releaseThreads(3); // wait until other threads are at this point
void* returnValue; void* returnValue;
result = pthread_join( add1Thread, &returnValue ); result = pthread_join( add1Thread, &returnValue );
if ( result != 0 ) { if ( result != 0 ) {
@ -276,20 +276,20 @@ int main()
return 1; return 1;
} }
std::cout << "Add1 returned " << intptr_t(returnValue) << std::endl; std::cout << "Add1 returned " << intptr_t(returnValue) << std::endl;
result = pthread_join( fibThread1, &returnValue ); result = pthread_join( fibThread1, &returnValue );
if ( result != 0 ) { if ( result != 0 ) {
std::cerr << "Could not join thread" << std::endl; std::cerr << "Could not join thread" << std::endl;
return 1; return 1;
} }
std::cout << "Fib1 returned " << intptr_t(returnValue) << std::endl; std::cout << "Fib1 returned " << intptr_t(returnValue) << std::endl;
result = pthread_join( fibThread2, &returnValue ); result = pthread_join( fibThread2, &returnValue );
if ( result != 0 ) { if ( result != 0 ) {
std::cerr << "Could not join thread" << std::endl; std::cerr << "Could not join thread" << std::endl;
return 1; return 1;
} }
std::cout << "Fib2 returned " << intptr_t(returnValue) << std::endl; std::cout << "Fib2 returned " << intptr_t(returnValue) << std::endl;
return 0; return 0;
} }

View File

@ -418,7 +418,7 @@ DSGraph &BUDataStructures::CreateGraphForExternalFunction(const Function &Fn) {
DSG->getReturnNodes().insert(std::make_pair(F, DSNodeHandle())); DSG->getReturnNodes().insert(std::make_pair(F, DSNodeHandle()));
if (F->getName() == "free") { // Taking the address of free. if (F->getName() == "free") { // Taking the address of free.
// Free should take a single pointer argument, mark it as heap memory. // Free should take a single pointer argument, mark it as heap memory.
DSNode *N = new DSNode(0, DSG); DSNode *N = new DSNode(0, DSG);
N->setHeapNodeMarker(); N->setHeapNodeMarker();

View File

@ -682,9 +682,9 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
const Type* ArgTy = getValue(iType, Oprnds[0])->getType(); const Type* ArgTy = getValue(iType, Oprnds[0])->getType();
Function* NF = TheModule->getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, 0); Function* NF = TheModule->getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, 0);
//b = vaarg a, t -> //b = vaarg a, t ->
//foo = alloca 1 of t //foo = alloca 1 of t
//bar = vacopy a //bar = vacopy a
//store bar -> foo //store bar -> foo
//b = vaarg foo, t //b = vaarg foo, t
AllocaInst* foo = new AllocaInst(ArgTy, 0, "vaarg.fix"); AllocaInst* foo = new AllocaInst(ArgTy, 0, "vaarg.fix");

View File

@ -170,17 +170,17 @@ static ModuleProvider* CheckVarargs(ModuleProvider* MP) {
if(Function* F = M->getNamedFunction("llvm.va_start")) { if(Function* F = M->getNamedFunction("llvm.va_start")) {
assert(F->arg_size() == 0 && "Obsolete va_start takes 0 argument!"); assert(F->arg_size() == 0 && "Obsolete va_start takes 0 argument!");
//foo = va_start() //foo = va_start()
// -> // ->
//bar = alloca typeof(foo) //bar = alloca typeof(foo)
//va_start(bar) //va_start(bar)
//foo = load bar //foo = load bar
const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID); const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID);
const Type* ArgTy = F->getFunctionType()->getReturnType(); const Type* ArgTy = F->getFunctionType()->getReturnType();
const Type* ArgTyPtr = PointerType::get(ArgTy); const Type* ArgTyPtr = PointerType::get(ArgTy);
Function* NF = M->getOrInsertFunction("llvm.va_start", Function* NF = M->getOrInsertFunction("llvm.va_start",
RetTy, ArgTyPtr, 0); RetTy, ArgTyPtr, 0);
for(Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E;) for(Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E;)
@ -193,7 +193,7 @@ static ModuleProvider* CheckVarargs(ModuleProvider* MP) {
} }
F->setName(""); F->setName("");
} }
if(Function* F = M->getNamedFunction("llvm.va_end")) { if(Function* F = M->getNamedFunction("llvm.va_end")) {
assert(F->arg_size() == 1 && "Obsolete va_end takes 1 argument!"); assert(F->arg_size() == 1 && "Obsolete va_end takes 1 argument!");
//vaend foo //vaend foo
@ -203,9 +203,9 @@ static ModuleProvider* CheckVarargs(ModuleProvider* MP) {
const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID); const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID);
const Type* ArgTy = F->getFunctionType()->getParamType(0); const Type* ArgTy = F->getFunctionType()->getParamType(0);
const Type* ArgTyPtr = PointerType::get(ArgTy); const Type* ArgTyPtr = PointerType::get(ArgTy);
Function* NF = M->getOrInsertFunction("llvm.va_end", Function* NF = M->getOrInsertFunction("llvm.va_end",
RetTy, ArgTyPtr, 0); RetTy, ArgTyPtr, 0);
for(Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E;) for(Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E;)
if (CallInst* CI = dyn_cast<CallInst>(*I++)) { if (CallInst* CI = dyn_cast<CallInst>(*I++)) {
AllocaInst* bar = new AllocaInst(ArgTy, 0, "vaend.fix.1", CI); AllocaInst* bar = new AllocaInst(ArgTy, 0, "vaend.fix.1", CI);
@ -215,7 +215,7 @@ static ModuleProvider* CheckVarargs(ModuleProvider* MP) {
} }
F->setName(""); F->setName("");
} }
if(Function* F = M->getNamedFunction("llvm.va_copy")) { if(Function* F = M->getNamedFunction("llvm.va_copy")) {
assert(F->arg_size() == 1 && "Obsolete va_copy takes 1 argument!"); assert(F->arg_size() == 1 && "Obsolete va_copy takes 1 argument!");
//foo = vacopy(bar) //foo = vacopy(bar)
@ -225,13 +225,13 @@ static ModuleProvider* CheckVarargs(ModuleProvider* MP) {
//store bar -> b //store bar -> b
//vacopy(a, b) //vacopy(a, b)
//foo = load a //foo = load a
const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID); const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID);
const Type* ArgTy = F->getFunctionType()->getReturnType(); const Type* ArgTy = F->getFunctionType()->getReturnType();
const Type* ArgTyPtr = PointerType::get(ArgTy); const Type* ArgTyPtr = PointerType::get(ArgTy);
Function* NF = M->getOrInsertFunction("llvm.va_copy", Function* NF = M->getOrInsertFunction("llvm.va_copy",
RetTy, ArgTyPtr, ArgTyPtr, 0); RetTy, ArgTyPtr, ArgTyPtr, 0);
for(Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E;) for(Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E;)
if (CallInst* CI = dyn_cast<CallInst>(*I++)) { if (CallInst* CI = dyn_cast<CallInst>(*I++)) {
AllocaInst* a = new AllocaInst(ArgTy, 0, "vacopy.fix.1", CI); AllocaInst* a = new AllocaInst(ArgTy, 0, "vacopy.fix.1", CI);

View File

@ -628,7 +628,7 @@ void BytecodeWriter::outputInstruction(const Instruction &I) {
Opcode = 57; // FastCC invoke. Opcode = 57; // FastCC invoke.
else if (II->getCallingConv() != CallingConv::C) else if (II->getCallingConv() != CallingConv::C)
Opcode = 56; // Invoke escape sequence. Opcode = 56; // Invoke escape sequence.
} else if (isa<LoadInst>(I) && cast<LoadInst>(I).isVolatile()) { } else if (isa<LoadInst>(I) && cast<LoadInst>(I).isVolatile()) {
Opcode = 62; Opcode = 62;
} else if (isa<StoreInst>(I) && cast<StoreInst>(I).isVolatile()) { } else if (isa<StoreInst>(I) && cast<StoreInst>(I).isVolatile()) {

View File

@ -108,15 +108,15 @@ void ELFCodeEmitter::startFunction(MachineFunction &F) {
ELFWriter::ELFSection::SHF_EXECINSTR | ELFWriter::ELFSection::SHF_EXECINSTR |
ELFWriter::ELFSection::SHF_ALLOC); ELFWriter::ELFSection::SHF_ALLOC);
OutBuffer = &ES->SectionData; OutBuffer = &ES->SectionData;
// Upgrade the section alignment if required. // Upgrade the section alignment if required.
if (ES->Align < Align) ES->Align = Align; if (ES->Align < Align) ES->Align = Align;
// Add padding zeros to the end of the buffer to make sure that the // Add padding zeros to the end of the buffer to make sure that the
// function will start on the correct byte alignment within the section. // function will start on the correct byte alignment within the section.
size_t SectionOff = OutBuffer->size(); size_t SectionOff = OutBuffer->size();
ELFWriter::align(*OutBuffer, Align); ELFWriter::align(*OutBuffer, Align);
FnStart = OutBuffer->size(); FnStart = OutBuffer->size();
} }
@ -125,7 +125,7 @@ void ELFCodeEmitter::startFunction(MachineFunction &F) {
void ELFCodeEmitter::finishFunction(MachineFunction &F) { void ELFCodeEmitter::finishFunction(MachineFunction &F) {
// We now know the size of the function, add a symbol to represent it. // We now know the size of the function, add a symbol to represent it.
ELFWriter::ELFSym FnSym(F.getFunction()); ELFWriter::ELFSym FnSym(F.getFunction());
// Figure out the binding (linkage) of the symbol. // Figure out the binding (linkage) of the symbol.
switch (F.getFunction()->getLinkage()) { switch (F.getFunction()->getLinkage()) {
default: default:
@ -149,7 +149,7 @@ void ELFCodeEmitter::finishFunction(MachineFunction &F) {
FnSym.SectionIdx = ES->SectionIdx; FnSym.SectionIdx = ES->SectionIdx;
FnSym.Value = FnStart; // Value = Offset from start of Section. FnSym.Value = FnStart; // Value = Offset from start of Section.
FnSym.Size = OutBuffer->size()-FnStart; FnSym.Size = OutBuffer->size()-FnStart;
// Finally, add it to the symtab. // Finally, add it to the symtab.
EW.SymbolTable.push_back(FnSym); EW.SymbolTable.push_back(FnSym);
} }
@ -162,7 +162,7 @@ ELFWriter::ELFWriter(std::ostream &o, TargetMachine &tm) : O(o), TM(tm) {
e_machine = 0; // e_machine defaults to 'No Machine' e_machine = 0; // e_machine defaults to 'No Machine'
e_flags = 0; // e_flags defaults to 0, no flags. e_flags = 0; // e_flags defaults to 0, no flags.
is64Bit = TM.getTargetData().getPointerSizeInBits() == 64; is64Bit = TM.getTargetData().getPointerSizeInBits() == 64;
isLittleEndian = TM.getTargetData().isLittleEndian(); isLittleEndian = TM.getTargetData().isLittleEndian();
// Create the machine code emitter object for this target. // Create the machine code emitter object for this target.
@ -181,7 +181,7 @@ bool ELFWriter::doInitialization(Module &M) {
// Local alias to shortenify coming code. // Local alias to shortenify coming code.
std::vector<unsigned char> &FH = FileHeader; std::vector<unsigned char> &FH = FileHeader;
outbyte(FH, 0x7F); // EI_MAG0 outbyte(FH, 0x7F); // EI_MAG0
outbyte(FH, 'E'); // EI_MAG1 outbyte(FH, 'E'); // EI_MAG1
outbyte(FH, 'L'); // EI_MAG2 outbyte(FH, 'L'); // EI_MAG2
@ -190,7 +190,7 @@ bool ELFWriter::doInitialization(Module &M) {
outbyte(FH, isLittleEndian ? 1 : 2); // EI_DATA outbyte(FH, isLittleEndian ? 1 : 2); // EI_DATA
outbyte(FH, 1); // EI_VERSION outbyte(FH, 1); // EI_VERSION
FH.resize(16); // EI_PAD up to 16 bytes. FH.resize(16); // EI_PAD up to 16 bytes.
// This should change for shared objects. // This should change for shared objects.
outhalf(FH, 1); // e_type = ET_REL outhalf(FH, 1); // e_type = ET_REL
outhalf(FH, e_machine); // e_machine = whatever the target wants outhalf(FH, e_machine); // e_machine = whatever the target wants
@ -207,7 +207,7 @@ bool ELFWriter::doInitialization(Module &M) {
outhalf(FH, 0); // e_phnum = # prog header entries = 0 outhalf(FH, 0); // e_phnum = # prog header entries = 0
outhalf(FH, is64Bit ? 64 : 40); // e_shentsize = sect hdr entry size outhalf(FH, is64Bit ? 64 : 40); // e_shentsize = sect hdr entry size
ELFHeader_e_shnum_Offset = FH.size(); ELFHeader_e_shnum_Offset = FH.size();
outhalf(FH, 0); // e_shnum = # of section header ents outhalf(FH, 0); // e_shnum = # of section header ents
ELFHeader_e_shstrndx_Offset = FH.size(); ELFHeader_e_shstrndx_Offset = FH.size();
@ -235,7 +235,7 @@ void ELFWriter::EmitGlobal(GlobalVariable *GV) {
SymbolTable.push_back(ExternalSym); SymbolTable.push_back(ExternalSym);
return; return;
} }
const Type *GVType = (const Type*)GV->getType(); const Type *GVType = (const Type*)GV->getType();
unsigned Align = TM.getTargetData().getTypeAlignment(GVType); unsigned Align = TM.getTargetData().getTypeAlignment(GVType);
unsigned Size = TM.getTargetData().getTypeSize(GVType); unsigned Size = TM.getTargetData().getTypeSize(GVType);
@ -473,11 +473,11 @@ void ELFWriter::OutputSectionsAndSectionTable() {
// Now that we know where all of the sections will be emitted, set the e_shnum // Now that we know where all of the sections will be emitted, set the e_shnum
// entry in the ELF header. // entry in the ELF header.
fixhalf(FileHeader, NumSections, ELFHeader_e_shnum_Offset); fixhalf(FileHeader, NumSections, ELFHeader_e_shnum_Offset);
// Now that we know the offset in the file of the section table, update the // Now that we know the offset in the file of the section table, update the
// e_shoff address in the ELF header. // e_shoff address in the ELF header.
fixaddr(FileHeader, FileOff, ELFHeader_e_shoff_Offset); fixaddr(FileHeader, FileOff, ELFHeader_e_shoff_Offset);
// Now that we know all of the data in the file header, emit it and all of the // Now that we know all of the data in the file header, emit it and all of the
// sections! // sections!
O.write((char*)&FileHeader[0], FileHeader.size()); O.write((char*)&FileHeader[0], FileHeader.size());
@ -516,7 +516,7 @@ void ELFWriter::OutputSectionsAndSectionTable() {
for (size_t NewFileOff = (FileOff+TableAlign-1) & ~(TableAlign-1); for (size_t NewFileOff = (FileOff+TableAlign-1) & ~(TableAlign-1);
FileOff != NewFileOff; ++FileOff) FileOff != NewFileOff; ++FileOff)
O.put(0xAB); O.put(0xAB);
// Emit the section table itself. // Emit the section table itself.
O.write((char*)&Table[0], Table.size()); O.write((char*)&Table[0], Table.size());
} }

View File

@ -150,7 +150,7 @@ static Value *LowerCTPOP(Value *V, Instruction *IP) {
ConstantExpr::getCast(ConstantUInt::get(Type::ULongTy, ConstantExpr::getCast(ConstantUInt::get(Type::ULongTy,
MaskValues[ct]), V->getType()); MaskValues[ct]), V->getType());
Value *LHS = BinaryOperator::createAnd(V, MaskCst, "cppop.and1", IP); Value *LHS = BinaryOperator::createAnd(V, MaskCst, "cppop.and1", IP);
Value *VShift = new ShiftInst(Instruction::Shr, V, Value *VShift = new ShiftInst(Instruction::Shr, V,
ConstantInt::get(Type::UByteTy, i), "ctpop.sh", IP); ConstantInt::get(Type::UByteTy, i), "ctpop.sh", IP);
Value *RHS = BinaryOperator::createAnd(VShift, MaskCst, "cppop.and2", IP); Value *RHS = BinaryOperator::createAnd(VShift, MaskCst, "cppop.and2", IP);
V = BinaryOperator::createAdd(LHS, RHS, "ctpop.step", IP); V = BinaryOperator::createAdd(LHS, RHS, "ctpop.step", IP);

View File

@ -128,7 +128,7 @@ private:
SDOperand ExpandLegalUINT_TO_FP(SDOperand LegalOp, MVT::ValueType DestVT); SDOperand ExpandLegalUINT_TO_FP(SDOperand LegalOp, MVT::ValueType DestVT);
SDOperand PromoteLegalINT_TO_FP(SDOperand LegalOp, MVT::ValueType DestVT, SDOperand PromoteLegalINT_TO_FP(SDOperand LegalOp, MVT::ValueType DestVT,
bool isSigned); bool isSigned);
bool ExpandShift(unsigned Opc, SDOperand Op, SDOperand Amt, bool ExpandShift(unsigned Opc, SDOperand Op, SDOperand Amt,
SDOperand &Lo, SDOperand &Hi); SDOperand &Lo, SDOperand &Hi);
void ExpandShiftParts(unsigned NodeOp, SDOperand Op, SDOperand Amt, void ExpandShiftParts(unsigned NodeOp, SDOperand Op, SDOperand Amt,
@ -152,22 +152,22 @@ SelectionDAGLegalize::SelectionDAGLegalize(SelectionDAG &dag)
"Too many value types for ValueTypeActions to hold!"); "Too many value types for ValueTypeActions to hold!");
} }
/// ExpandLegalUINT_TO_FP - This function is responsible for legalizing a /// ExpandLegalUINT_TO_FP - This function is responsible for legalizing a
/// UINT_TO_FP operation of the specified operand when the target requests that /// UINT_TO_FP operation of the specified operand when the target requests that
/// we expand it. At this point, we know that the result and operand types are /// we expand it. At this point, we know that the result and operand types are
/// legal for the target. /// legal for the target.
SDOperand SelectionDAGLegalize::ExpandLegalUINT_TO_FP(SDOperand Op0, SDOperand SelectionDAGLegalize::ExpandLegalUINT_TO_FP(SDOperand Op0,
MVT::ValueType DestVT) { MVT::ValueType DestVT) {
SDOperand Tmp1 = DAG.getNode(ISD::SINT_TO_FP, DestVT, Op0); SDOperand Tmp1 = DAG.getNode(ISD::SINT_TO_FP, DestVT, Op0);
SDOperand SignSet = DAG.getSetCC(ISD::SETLT, TLI.getSetCCResultTy(), SDOperand SignSet = DAG.getSetCC(ISD::SETLT, TLI.getSetCCResultTy(),
Op0, Op0,
DAG.getConstant(0, DAG.getConstant(0,
Op0.getValueType())); Op0.getValueType()));
SDOperand Zero = getIntPtrConstant(0), Four = getIntPtrConstant(4); SDOperand Zero = getIntPtrConstant(0), Four = getIntPtrConstant(4);
SDOperand CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(), SDOperand CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(),
SignSet, Four, Zero); SignSet, Four, Zero);
// If the sign bit of the integer is set, the large number will be treated as // If the sign bit of the integer is set, the large number will be treated as
// a negative number. To counteract this, the dynamic code adds an offset // a negative number. To counteract this, the dynamic code adds an offset
// depending on the data type. // depending on the data type.
@ -181,7 +181,7 @@ SDOperand SelectionDAGLegalize::ExpandLegalUINT_TO_FP(SDOperand Op0,
} }
if (TLI.isLittleEndian()) FF <<= 32; if (TLI.isLittleEndian()) FF <<= 32;
static Constant *FudgeFactor = ConstantUInt::get(Type::ULongTy, FF); static Constant *FudgeFactor = ConstantUInt::get(Type::ULongTy, FF);
MachineConstantPool *CP = DAG.getMachineFunction().getConstantPool(); MachineConstantPool *CP = DAG.getMachineFunction().getConstantPool();
SDOperand CPIdx = DAG.getConstantPool(CP->getConstantPoolIndex(FudgeFactor), SDOperand CPIdx = DAG.getConstantPool(CP->getConstantPoolIndex(FudgeFactor),
TLI.getPointerTy()); TLI.getPointerTy());
@ -196,12 +196,12 @@ SDOperand SelectionDAGLegalize::ExpandLegalUINT_TO_FP(SDOperand Op0,
DAG.getEntryNode(), CPIdx, DAG.getEntryNode(), CPIdx,
DAG.getSrcValue(NULL), MVT::f32)); DAG.getSrcValue(NULL), MVT::f32));
} }
NeedsAnotherIteration = true; NeedsAnotherIteration = true;
return DAG.getNode(ISD::ADD, DestVT, Tmp1, FudgeInReg); return DAG.getNode(ISD::ADD, DestVT, Tmp1, FudgeInReg);
} }
/// PromoteLegalUINT_TO_FP - This function is responsible for legalizing a /// PromoteLegalUINT_TO_FP - This function is responsible for legalizing a
/// UINT_TO_FP operation of the specified operand when the target requests that /// UINT_TO_FP operation of the specified operand when the target requests that
/// we promote it. At this point, we know that the result and operand types are /// we promote it. At this point, we know that the result and operand types are
/// legal for the target, and that there is a legal UINT_TO_FP or SINT_TO_FP /// legal for the target, and that there is a legal UINT_TO_FP or SINT_TO_FP
@ -211,14 +211,14 @@ SDOperand SelectionDAGLegalize::PromoteLegalINT_TO_FP(SDOperand LegalOp,
bool isSigned) { bool isSigned) {
// First step, figure out the appropriate *INT_TO_FP operation to use. // First step, figure out the appropriate *INT_TO_FP operation to use.
MVT::ValueType NewInTy = LegalOp.getValueType(); MVT::ValueType NewInTy = LegalOp.getValueType();
unsigned OpToUse = 0; unsigned OpToUse = 0;
// Scan for the appropriate larger type to use. // Scan for the appropriate larger type to use.
while (1) { while (1) {
NewInTy = (MVT::ValueType)(NewInTy+1); NewInTy = (MVT::ValueType)(NewInTy+1);
assert(MVT::isInteger(NewInTy) && "Ran out of possibilities!"); assert(MVT::isInteger(NewInTy) && "Ran out of possibilities!");
// If the target supports SINT_TO_FP of this type, use it. // If the target supports SINT_TO_FP of this type, use it.
switch (TLI.getOperationAction(ISD::SINT_TO_FP, NewInTy)) { switch (TLI.getOperationAction(ISD::SINT_TO_FP, NewInTy)) {
default: break; default: break;
@ -232,7 +232,7 @@ SDOperand SelectionDAGLegalize::PromoteLegalINT_TO_FP(SDOperand LegalOp,
} }
if (OpToUse) break; if (OpToUse) break;
if (isSigned) continue; if (isSigned) continue;
// If the target supports UINT_TO_FP of this type, use it. // If the target supports UINT_TO_FP of this type, use it.
switch (TLI.getOperationAction(ISD::UINT_TO_FP, NewInTy)) { switch (TLI.getOperationAction(ISD::UINT_TO_FP, NewInTy)) {
default: break; default: break;
@ -245,13 +245,13 @@ SDOperand SelectionDAGLegalize::PromoteLegalINT_TO_FP(SDOperand LegalOp,
break; break;
} }
if (OpToUse) break; if (OpToUse) break;
// Otherwise, try a larger type. // Otherwise, try a larger type.
} }
// Make sure to legalize any nodes we create here in the next pass. // Make sure to legalize any nodes we create here in the next pass.
NeedsAnotherIteration = true; NeedsAnotherIteration = true;
// Okay, we found the operation and type to use. Zero extend our input to the // Okay, we found the operation and type to use. Zero extend our input to the
// desired type then run the operation on it. // desired type then run the operation on it.
return DAG.getNode(OpToUse, DestVT, return DAG.getNode(OpToUse, DestVT,
@ -760,7 +760,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
float F; float F;
} V; } V;
V.F = CFP->getValue(); V.F = CFP->getValue();
Result = DAG.getNode(ISD::STORE, MVT::Other, Tmp1, Result = DAG.getNode(ISD::STORE, MVT::Other, Tmp1,
DAG.getConstant(V.I, MVT::i32), Tmp2, DAG.getConstant(V.I, MVT::i32), Tmp2,
Node->getOperand(3)); Node->getOperand(3));
} else { } else {
@ -770,7 +770,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
double F; double F;
} V; } V;
V.F = CFP->getValue(); V.F = CFP->getValue();
Result = DAG.getNode(ISD::STORE, MVT::Other, Tmp1, Result = DAG.getNode(ISD::STORE, MVT::Other, Tmp1,
DAG.getConstant(V.I, MVT::i64), Tmp2, DAG.getConstant(V.I, MVT::i64), Tmp2,
Node->getOperand(3)); Node->getOperand(3));
} }
@ -1282,15 +1282,15 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
break; break;
case ISD::CTTZ: case ISD::CTTZ:
//if Tmp1 == sizeinbits(NVT) then Tmp1 = sizeinbits(Old VT) //if Tmp1 == sizeinbits(NVT) then Tmp1 = sizeinbits(Old VT)
Tmp2 = DAG.getSetCC(ISD::SETEQ, TLI.getSetCCResultTy(), Tmp1, Tmp2 = DAG.getSetCC(ISD::SETEQ, TLI.getSetCCResultTy(), Tmp1,
DAG.getConstant(getSizeInBits(NVT), NVT)); DAG.getConstant(getSizeInBits(NVT), NVT));
Result = DAG.getNode(ISD::SELECT, NVT, Tmp2, Result = DAG.getNode(ISD::SELECT, NVT, Tmp2,
DAG.getConstant(getSizeInBits(OVT),NVT), Tmp1); DAG.getConstant(getSizeInBits(OVT),NVT), Tmp1);
break; break;
case ISD::CTLZ: case ISD::CTLZ:
//Tmp1 = Tmp1 - (sizeinbits(NVT) - sizeinbits(Old VT)) //Tmp1 = Tmp1 - (sizeinbits(NVT) - sizeinbits(Old VT))
Result = DAG.getNode(ISD::SUB, NVT, Tmp1, Result = DAG.getNode(ISD::SUB, NVT, Tmp1,
DAG.getConstant(getSizeInBits(NVT) - DAG.getConstant(getSizeInBits(NVT) -
getSizeInBits(OVT), NVT)); getSizeInBits(OVT), NVT));
break; break;
} }
@ -1314,7 +1314,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
//x = (x & mask[i][len/8]) + (x >> (1 << i) & mask[i][len/8]) //x = (x & mask[i][len/8]) + (x >> (1 << i) & mask[i][len/8])
Tmp2 = DAG.getConstant(mask[i], VT); Tmp2 = DAG.getConstant(mask[i], VT);
Tmp3 = DAG.getConstant(1ULL << i, ShVT); Tmp3 = DAG.getConstant(1ULL << i, ShVT);
Tmp1 = DAG.getNode(ISD::ADD, VT, Tmp1 = DAG.getNode(ISD::ADD, VT,
DAG.getNode(ISD::AND, VT, Tmp1, Tmp2), DAG.getNode(ISD::AND, VT, Tmp1, Tmp2),
DAG.getNode(ISD::AND, VT, DAG.getNode(ISD::AND, VT,
DAG.getNode(ISD::SRL, VT, Tmp1, Tmp3), DAG.getNode(ISD::SRL, VT, Tmp1, Tmp3),
@ -1329,16 +1329,16 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
x = x | (x >> 2); x = x | (x >> 2);
... ...
x = x | (x >>16); x = x | (x >>16);
x = x | (x >>32); // for 64-bit input x = x | (x >>32); // for 64-bit input
return popcount(~x); return popcount(~x);
but see also: http://www.hackersdelight.org/HDcode/nlz.cc */ but see also: http://www.hackersdelight.org/HDcode/nlz.cc */
MVT::ValueType VT = Tmp1.getValueType(); MVT::ValueType VT = Tmp1.getValueType();
MVT::ValueType ShVT = TLI.getShiftAmountTy(); MVT::ValueType ShVT = TLI.getShiftAmountTy();
unsigned len = getSizeInBits(VT); unsigned len = getSizeInBits(VT);
for (unsigned i = 0; (1U << i) <= (len / 2); ++i) { for (unsigned i = 0; (1U << i) <= (len / 2); ++i) {
Tmp3 = DAG.getConstant(1ULL << i, ShVT); Tmp3 = DAG.getConstant(1ULL << i, ShVT);
Tmp1 = DAG.getNode(ISD::OR, VT, Tmp1, Tmp1 = DAG.getNode(ISD::OR, VT, Tmp1,
DAG.getNode(ISD::SRL, VT, Tmp1, Tmp3)); DAG.getNode(ISD::SRL, VT, Tmp1, Tmp3));
} }
Tmp3 = DAG.getNode(ISD::XOR, VT, Tmp1, DAG.getConstant(~0ULL, VT)); Tmp3 = DAG.getNode(ISD::XOR, VT, Tmp1, DAG.getConstant(~0ULL, VT));
@ -1346,20 +1346,20 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
break; break;
} }
case ISD::CTTZ: { case ISD::CTTZ: {
// for now, we use: { return popcount(~x & (x - 1)); } // for now, we use: { return popcount(~x & (x - 1)); }
// unless the target has ctlz but not ctpop, in which case we use: // unless the target has ctlz but not ctpop, in which case we use:
// { return 32 - nlz(~x & (x-1)); } // { return 32 - nlz(~x & (x-1)); }
// see also http://www.hackersdelight.org/HDcode/ntz.cc // see also http://www.hackersdelight.org/HDcode/ntz.cc
MVT::ValueType VT = Tmp1.getValueType(); MVT::ValueType VT = Tmp1.getValueType();
Tmp2 = DAG.getConstant(~0ULL, VT); Tmp2 = DAG.getConstant(~0ULL, VT);
Tmp3 = DAG.getNode(ISD::AND, VT, Tmp3 = DAG.getNode(ISD::AND, VT,
DAG.getNode(ISD::XOR, VT, Tmp1, Tmp2), DAG.getNode(ISD::XOR, VT, Tmp1, Tmp2),
DAG.getNode(ISD::SUB, VT, Tmp1, DAG.getNode(ISD::SUB, VT, Tmp1,
DAG.getConstant(1, VT))); DAG.getConstant(1, VT)));
// If ISD::CTLZ is legal and CTPOP isn't, then do that instead // If ISD::CTLZ is legal and CTPOP isn't, then do that instead
if (TLI.getOperationAction(ISD::CTPOP, VT) != TargetLowering::Legal && if (TLI.getOperationAction(ISD::CTPOP, VT) != TargetLowering::Legal &&
TLI.getOperationAction(ISD::CTLZ, VT) == TargetLowering::Legal) { TLI.getOperationAction(ISD::CTLZ, VT) == TargetLowering::Legal) {
Result = LegalizeOp(DAG.getNode(ISD::SUB, VT, Result = LegalizeOp(DAG.getNode(ISD::SUB, VT,
DAG.getConstant(getSizeInBits(VT), VT), DAG.getConstant(getSizeInBits(VT), VT),
DAG.getNode(ISD::CTLZ, VT, Tmp3))); DAG.getNode(ISD::CTLZ, VT, Tmp3)));
} else { } else {
@ -1374,7 +1374,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
break; break;
} }
break; break;
// Unary operators // Unary operators
case ISD::FABS: case ISD::FABS:
case ISD::FNEG: case ISD::FNEG:
@ -1453,7 +1453,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
if (Node->getOpcode() == ISD::UINT_TO_FP || if (Node->getOpcode() == ISD::UINT_TO_FP ||
Node->getOpcode() == ISD::SINT_TO_FP) { Node->getOpcode() == ISD::SINT_TO_FP) {
bool isSigned = Node->getOpcode() == ISD::SINT_TO_FP; bool isSigned = Node->getOpcode() == ISD::SINT_TO_FP;
switch (TLI.getOperationAction(Node->getOpcode(), switch (TLI.getOperationAction(Node->getOpcode(),
Node->getOperand(0).getValueType())) { Node->getOperand(0).getValueType())) {
default: assert(0 && "Unknown operation action!"); default: assert(0 && "Unknown operation action!");
case TargetLowering::Expand: case TargetLowering::Expand:
@ -1936,15 +1936,15 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
break; break;
case ISD::CTTZ: case ISD::CTTZ:
//if Tmp1 == sizeinbits(NVT) then Tmp1 = sizeinbits(Old VT) //if Tmp1 == sizeinbits(NVT) then Tmp1 = sizeinbits(Old VT)
Tmp2 = DAG.getSetCC(ISD::SETEQ, MVT::i1, Tmp1, Tmp2 = DAG.getSetCC(ISD::SETEQ, MVT::i1, Tmp1,
DAG.getConstant(getSizeInBits(NVT), NVT)); DAG.getConstant(getSizeInBits(NVT), NVT));
Result = DAG.getNode(ISD::SELECT, NVT, Tmp2, Result = DAG.getNode(ISD::SELECT, NVT, Tmp2,
DAG.getConstant(getSizeInBits(VT),NVT), Tmp1); DAG.getConstant(getSizeInBits(VT),NVT), Tmp1);
break; break;
case ISD::CTLZ: case ISD::CTLZ:
//Tmp1 = Tmp1 - (sizeinbits(NVT) - sizeinbits(Old VT)) //Tmp1 = Tmp1 - (sizeinbits(NVT) - sizeinbits(Old VT))
Result = DAG.getNode(ISD::SUB, NVT, Tmp1, Result = DAG.getNode(ISD::SUB, NVT, Tmp1,
DAG.getConstant(getSizeInBits(NVT) - DAG.getConstant(getSizeInBits(NVT) -
getSizeInBits(VT), NVT)); getSizeInBits(VT), NVT));
break; break;
} }
@ -2282,7 +2282,7 @@ static SDOperand FindInputOutputChains(SDNode *OpNode, SDNode *&OutChain,
return SDOperand(LatestCallSeqEnd, 0); return SDOperand(LatestCallSeqEnd, 0);
} }
/// SpliceCallInto - Given the result chain of a libcall (CallResult), and a /// SpliceCallInto - Given the result chain of a libcall (CallResult), and a
void SelectionDAGLegalize::SpliceCallInto(const SDOperand &CallResult, void SelectionDAGLegalize::SpliceCallInto(const SDOperand &CallResult,
SDNode *OutChain) { SDNode *OutChain) {
// Nothing to splice it into? // Nothing to splice it into?
@ -2558,7 +2558,7 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
unsigned IncrementSize = MVT::getSizeInBits(Lo.getValueType())/8; unsigned IncrementSize = MVT::getSizeInBits(Lo.getValueType())/8;
Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
getIntPtrConstant(IncrementSize)); getIntPtrConstant(IncrementSize));
//Is this safe? declaring that the two parts of the split load //Is this safe? declaring that the two parts of the split load
//are from the same instruction? //are from the same instruction?
Hi = DAG.getLoad(NVT, Ch, Ptr, Node->getOperand(2)); Hi = DAG.getLoad(NVT, Ch, Ptr, Node->getOperand(2));

View File

@ -1212,7 +1212,7 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
break; break;
case ISD::SUB: case ISD::SUB:
if (N1.getOpcode() == ISD::ADD) { if (N1.getOpcode() == ISD::ADD) {
if (N1.Val->getOperand(0) == N2 && if (N1.Val->getOperand(0) == N2 &&
!MVT::isFloatingPoint(N2.getValueType())) !MVT::isFloatingPoint(N2.getValueType()))
return N1.Val->getOperand(1); // (A+B)-A == B return N1.Val->getOperand(1); // (A+B)-A == B
if (N1.Val->getOperand(1) == N2 && if (N1.Val->getOperand(1) == N2 &&
@ -1233,7 +1233,7 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
if (N1.getOpcode() == ISD::SIGN_EXTEND_INREG) if (N1.getOpcode() == ISD::SIGN_EXTEND_INREG)
if (cast<VTSDNode>(N1.getOperand(1))->getVT() <= EVT) if (cast<VTSDNode>(N1.getOperand(1))->getVT() <= EVT)
return N1; return N1;
// If we are sign extending a sextload, return just the load. // If we are sign extending a sextload, return just the load.
if (N1.getOpcode() == ISD::SEXTLOAD) if (N1.getOpcode() == ISD::SEXTLOAD)
if (cast<VTSDNode>(N1.getOperand(3))->getVT() <= EVT) if (cast<VTSDNode>(N1.getOperand(3))->getVT() <= EVT)
@ -1311,7 +1311,7 @@ void SDNode::setAdjCallChain(SDOperand N) {
SDOperand SelectionDAG::getLoad(MVT::ValueType VT, SDOperand SelectionDAG::getLoad(MVT::ValueType VT,
SDOperand Chain, SDOperand Ptr, SDOperand Chain, SDOperand Ptr,
SDOperand SV) { SDOperand SV) {
SDNode *&N = Loads[std::make_pair(Ptr, std::make_pair(Chain, VT))]; SDNode *&N = Loads[std::make_pair(Ptr, std::make_pair(Chain, VT))];
if (N) return SDOperand(N, 0); if (N) return SDOperand(N, 0);
@ -1457,7 +1457,7 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
} }
SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
SDOperand N1, SDOperand N2, SDOperand N3, SDOperand N1, SDOperand N2, SDOperand N3,
SDOperand N4) { SDOperand N4) {
std::vector<SDOperand> Ops; std::vector<SDOperand> Ops;
Ops.reserve(4); Ops.reserve(4);

View File

@ -716,7 +716,7 @@ void SelectionDAGLowering::visitCall(CallInst &I) {
Ops.push_back(getValue(I.getOperand(1))); Ops.push_back(getValue(I.getOperand(1)));
Tmp = DAG.getNode(F->getIntrinsicID() == Intrinsic::readport ? Tmp = DAG.getNode(F->getIntrinsicID() == Intrinsic::readport ?
ISD::READPORT : ISD::READIO, VTs, Ops); ISD::READPORT : ISD::READIO, VTs, Ops);
setValue(&I, Tmp); setValue(&I, Tmp);
DAG.setRoot(Tmp.getValue(1)); DAG.setRoot(Tmp.getValue(1));
return; return;
@ -887,7 +887,7 @@ void SelectionDAGLowering::visitVAArg(VAArgInst &I) {
} }
void SelectionDAGLowering::visitVAEnd(CallInst &I) { void SelectionDAGLowering::visitVAEnd(CallInst &I) {
DAG.setRoot(TLI.LowerVAEnd(getRoot(), getValue(I.getOperand(1)), DAG.setRoot(TLI.LowerVAEnd(getRoot(), getValue(I.getOperand(1)),
I.getOperand(1), DAG)); I.getOperand(1), DAG));
} }

View File

@ -77,7 +77,7 @@ void Interpreter::runAtExitHandlers () {
/// run - Start execution with the specified function and arguments. /// run - Start execution with the specified function and arguments.
/// ///
GenericValue GenericValue
Interpreter::runFunction(Function *F, Interpreter::runFunction(Function *F,
const std::vector<GenericValue> &ArgValues) { const std::vector<GenericValue> &ArgValues) {
assert (F && "Function *F was null at entry to run()"); assert (F && "Function *F was null at entry to run()");

View File

@ -218,7 +218,7 @@ GenericValue JIT::runFunction(Function *F,
void JIT::runJITOnFunction(Function *F) { void JIT::runJITOnFunction(Function *F) {
static bool isAlreadyCodeGenerating = false; static bool isAlreadyCodeGenerating = false;
assert(!isAlreadyCodeGenerating && "Error: Recursive compilation detected!"); assert(!isAlreadyCodeGenerating && "Error: Recursive compilation detected!");
MutexGuard locked(lock); MutexGuard locked(lock);
// JIT the function // JIT the function

View File

@ -147,19 +147,19 @@ namespace {
/// StubToFunctionMap - Keep track of the function that each stub /// StubToFunctionMap - Keep track of the function that each stub
/// corresponds to. /// corresponds to.
std::map<void*, Function*> StubToFunctionMap; std::map<void*, Function*> StubToFunctionMap;
public: public:
std::map<Function*, void*>& getFunctionToStubMap(const MutexGuard& locked) { std::map<Function*, void*>& getFunctionToStubMap(const MutexGuard& locked) {
assert(locked.holds(TheJIT->lock)); assert(locked.holds(TheJIT->lock));
return FunctionToStubMap; return FunctionToStubMap;
} }
std::map<void*, Function*>& getStubToFunctionMap(const MutexGuard& locked) { std::map<void*, Function*>& getStubToFunctionMap(const MutexGuard& locked) {
assert(locked.holds(TheJIT->lock)); assert(locked.holds(TheJIT->lock));
return StubToFunctionMap; return StubToFunctionMap;
} }
}; };
/// JITResolver - Keep track of, and resolve, call sites for functions that /// JITResolver - Keep track of, and resolve, call sites for functions that
/// have not yet been compiled. /// have not yet been compiled.
class JITResolver { class JITResolver {
@ -340,12 +340,12 @@ namespace {
public: public:
JITEmitter(JIT &jit) JITEmitter(JIT &jit)
:MemMgr(jit.getJITInfo().needsGOT()), :MemMgr(jit.getJITInfo().needsGOT()),
nextGOTIndex(0) nextGOTIndex(0)
{ {
TheJIT = &jit; TheJIT = &jit;
DEBUG(std::cerr << DEBUG(std::cerr <<
(MemMgr.isManagingGOT() ? "JIT is managing GOT\n" (MemMgr.isManagingGOT() ? "JIT is managing GOT\n"
: "JIT is not managing GOT\n")); : "JIT is not managing GOT\n"));
} }
@ -431,14 +431,14 @@ void JITEmitter::finishFunction(MachineFunction &F) {
// If the target REALLY wants a stub for this function, emit it now. // If the target REALLY wants a stub for this function, emit it now.
if (!MR.doesntNeedFunctionStub()) if (!MR.doesntNeedFunctionStub())
ResultPtr = getJITResolver(this).getExternalFunctionStub(ResultPtr); ResultPtr = getJITResolver(this).getExternalFunctionStub(ResultPtr);
} else if (MR.isGlobalValue()) } else if (MR.isGlobalValue())
ResultPtr = getPointerToGlobal(MR.getGlobalValue(), ResultPtr = getPointerToGlobal(MR.getGlobalValue(),
CurBlock+MR.getMachineCodeOffset(), CurBlock+MR.getMachineCodeOffset(),
MR.doesntNeedFunctionStub()); MR.doesntNeedFunctionStub());
else //ConstantPoolIndex else //ConstantPoolIndex
ResultPtr = ResultPtr =
(void*)(intptr_t)getConstantPoolEntryAddress(MR.getConstantPoolIndex()); (void*)(intptr_t)getConstantPoolEntryAddress(MR.getConstantPoolIndex());
MR.setResultPointer(ResultPtr); MR.setResultPointer(ResultPtr);
// if we are managing the got, check to see if this pointer has all ready // if we are managing the got, check to see if this pointer has all ready

View File

@ -408,7 +408,7 @@ size_t Compressor::decompress(const char *in, size_t size,
// Decompress it // Decompress it
int bzerr = BZ_OK; int bzerr = BZ_OK;
while ( BZ_OK == (bzerr = BZ2_bzDecompress(&bzdata)) && while ( BZ_OK == (bzerr = BZ2_bzDecompress(&bzdata)) &&
bzdata.avail_in != 0 ) { bzdata.avail_in != 0 ) {
if (0 != getdata_uns(bzdata.next_out, bzdata.avail_out,cb,context)) { if (0 != getdata_uns(bzdata.next_out, bzdata.avail_out,cb,context)) {
BZ2_bzDecompressEnd(&bzdata); BZ2_bzDecompressEnd(&bzdata);

View File

@ -29,9 +29,9 @@ using namespace sys;
#include <stdlib.h> #include <stdlib.h>
// This variable is useful for situations where the pthread library has been // This variable is useful for situations where the pthread library has been
// compiled with weak linkage for its interface symbols. This allows the // compiled with weak linkage for its interface symbols. This allows the
// threading support to be turned off by simply not linking against -lpthread. // threading support to be turned off by simply not linking against -lpthread.
// In that situation, the value of pthread_mutex_init will be 0 and // In that situation, the value of pthread_mutex_init will be 0 and
// consequently pthread_enabled will be false. In such situations, all the // consequently pthread_enabled will be false. In such situations, all the
// pthread operations become no-ops and the functions all return false. If // pthread operations become no-ops and the functions all return false. If
// pthread_mutex_init does have an address, then mutex support is enabled. // pthread_mutex_init does have an address, then mutex support is enabled.
@ -48,7 +48,7 @@ Mutex::Mutex( bool recursive)
if (pthread_enabled) if (pthread_enabled)
{ {
// Declare the pthread_mutex data structures // Declare the pthread_mutex data structures
pthread_mutex_t* mutex = pthread_mutex_t* mutex =
static_cast<pthread_mutex_t*>(malloc(sizeof(pthread_mutex_t))); static_cast<pthread_mutex_t*>(malloc(sizeof(pthread_mutex_t)));
pthread_mutexattr_t attr; pthread_mutexattr_t attr;
@ -92,10 +92,10 @@ Mutex::~Mutex()
} }
} }
bool bool
Mutex::acquire() Mutex::acquire()
{ {
if (pthread_enabled) if (pthread_enabled)
{ {
pthread_mutex_t* mutex = reinterpret_cast<pthread_mutex_t*>(data_); pthread_mutex_t* mutex = reinterpret_cast<pthread_mutex_t*>(data_);
assert(mutex != 0); assert(mutex != 0);
@ -106,7 +106,7 @@ Mutex::acquire()
return false; return false;
} }
bool bool
Mutex::release() Mutex::release()
{ {
if (pthread_enabled) if (pthread_enabled)
@ -120,7 +120,7 @@ Mutex::release()
return false; return false;
} }
bool bool
Mutex::tryacquire() Mutex::tryacquire()
{ {
if (pthread_enabled) if (pthread_enabled)

View File

@ -169,11 +169,11 @@ int AlphaCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) {
rv = getAlphaRegNumber(MO.getReg()); rv = getAlphaRegNumber(MO.getReg());
} else if (MO.isImmediate()) { } else if (MO.isImmediate()) {
rv = MO.getImmedValue(); rv = MO.getImmedValue();
} else if (MO.isGlobalAddress() || MO.isExternalSymbol() } else if (MO.isGlobalAddress() || MO.isExternalSymbol()
|| MO.isConstantPoolIndex()) { || MO.isConstantPoolIndex()) {
DEBUG(std::cerr << MO << " is a relocated op for " << MI << "\n";); DEBUG(std::cerr << MO << " is a relocated op for " << MI << "\n";);
bool isExternal = MO.isExternalSymbol() || bool isExternal = MO.isExternalSymbol() ||
(MO.isGlobalAddress() && (MO.isGlobalAddress() &&
( MO.getGlobal()->hasWeakLinkage() || ( MO.getGlobal()->hasWeakLinkage() ||
MO.getGlobal()->isExternal()) ); MO.getGlobal()->isExternal()) );
unsigned Reloc = 0; unsigned Reloc = 0;
@ -213,7 +213,7 @@ int AlphaCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) {
true)); true));
else else
MCE.addRelocation(MachineRelocation((unsigned)MCE.getCurrentPCOffset(), MCE.addRelocation(MachineRelocation((unsigned)MCE.getCurrentPCOffset(),
Reloc, MO.getConstantPoolIndex(), Reloc, MO.getConstantPoolIndex(),
Offset)); Offset));
} else if (MO.isMachineBasicBlock()) { } else if (MO.isMachineBasicBlock()) {
unsigned* CurrPC = (unsigned*)(intptr_t)MCE.getCurrentPCValue(); unsigned* CurrPC = (unsigned*)(intptr_t)MCE.getCurrentPCValue();

View File

@ -64,7 +64,7 @@ namespace {
//Move an Ireg to a FPreg //Move an Ireg to a FPreg
ITOF, ITOF,
//Move a FPreg to an Ireg //Move a FPreg to an Ireg
FTOI, FTOI,
}; };
} }
} }
@ -93,7 +93,7 @@ namespace {
setOperationAction(ISD::EXTLOAD, MVT::i1, Promote); setOperationAction(ISD::EXTLOAD, MVT::i1, Promote);
setOperationAction(ISD::EXTLOAD, MVT::f32, Expand); setOperationAction(ISD::EXTLOAD, MVT::f32, Expand);
setOperationAction(ISD::ZEXTLOAD, MVT::i1, Promote); setOperationAction(ISD::ZEXTLOAD, MVT::i1, Promote);
setOperationAction(ISD::ZEXTLOAD, MVT::i32, Expand); setOperationAction(ISD::ZEXTLOAD, MVT::i32, Expand);
@ -164,7 +164,7 @@ namespace {
virtual std::pair<SDOperand,SDOperand> virtual std::pair<SDOperand,SDOperand>
LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
const Type *ArgTy, SelectionDAG &DAG); const Type *ArgTy, SelectionDAG &DAG);
void restoreGP(MachineBasicBlock* BB) void restoreGP(MachineBasicBlock* BB)
{ {
BuildMI(BB, Alpha::BIS, 2, Alpha::R29).addReg(GP).addReg(GP); BuildMI(BB, Alpha::BIS, 2, Alpha::R29).addReg(GP).addReg(GP);
@ -203,8 +203,8 @@ SDOperand AlphaTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
} else { } else {
int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8); int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8);
SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy()); SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other,
DAG.getEntryNode(), Op.getOperand(0), DAG.getEntryNode(), Op.getOperand(0),
StackSlot, DAG.getSrcValue(NULL)); StackSlot, DAG.getSrcValue(NULL));
SRC = DAG.getLoad(Op.getValueType(), Store.getValue(0), StackSlot, SRC = DAG.getLoad(Op.getValueType(), Store.getValue(0), StackSlot,
DAG.getSrcValue(NULL)); DAG.getSrcValue(NULL));
@ -289,7 +289,7 @@ AlphaTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG)
case MVT::i16: case MVT::i16:
case MVT::i32: case MVT::i32:
case MVT::i64: case MVT::i64:
args_int[count] = AddLiveIn(MF, args_int[count], args_int[count] = AddLiveIn(MF, args_int[count],
getRegClassFor(MVT::i64)); getRegClassFor(MVT::i64));
argt = DAG.getCopyFromReg(args_int[count], VT, DAG.getRoot()); argt = DAG.getCopyFromReg(args_int[count], VT, DAG.getRoot());
if (VT != MVT::i64) if (VT != MVT::i64)
@ -322,15 +322,15 @@ AlphaTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG)
int FI = MFI->CreateFixedObject(8, -8 * (6 - i)); int FI = MFI->CreateFixedObject(8, -8 * (6 - i));
if (i == 0) VarArgsBase = FI; if (i == 0) VarArgsBase = FI;
SDOperand SDFI = DAG.getFrameIndex(FI, MVT::i64); SDOperand SDFI = DAG.getFrameIndex(FI, MVT::i64);
LS.push_back(DAG.getNode(ISD::STORE, MVT::Other, DAG.getRoot(), argt, LS.push_back(DAG.getNode(ISD::STORE, MVT::Other, DAG.getRoot(), argt,
SDFI, DAG.getSrcValue(NULL))); SDFI, DAG.getSrcValue(NULL)));
if (args_float[i] < 1024) if (args_float[i] < 1024)
args_float[i] = AddLiveIn(MF,args_float[i], getRegClassFor(MVT::f64)); args_float[i] = AddLiveIn(MF,args_float[i], getRegClassFor(MVT::f64));
argt = DAG.getCopyFromReg(args_float[i], MVT::f64, DAG.getRoot()); argt = DAG.getCopyFromReg(args_float[i], MVT::f64, DAG.getRoot());
FI = MFI->CreateFixedObject(8, - 8 * (12 - i)); FI = MFI->CreateFixedObject(8, - 8 * (12 - i));
SDFI = DAG.getFrameIndex(FI, MVT::i64); SDFI = DAG.getFrameIndex(FI, MVT::i64);
LS.push_back(DAG.getNode(ISD::STORE, MVT::Other, DAG.getRoot(), argt, LS.push_back(DAG.getNode(ISD::STORE, MVT::Other, DAG.getRoot(), argt,
SDFI, DAG.getSrcValue(NULL))); SDFI, DAG.getSrcValue(NULL)));
} }
@ -363,7 +363,7 @@ std::pair<SDOperand, SDOperand>
AlphaTargetLowering::LowerCallTo(SDOperand Chain, AlphaTargetLowering::LowerCallTo(SDOperand Chain,
const Type *RetTy, bool isVarArg, const Type *RetTy, bool isVarArg,
unsigned CallingConv, bool isTailCall, unsigned CallingConv, bool isTailCall,
SDOperand Callee, ArgListTy &Args, SDOperand Callee, ArgListTy &Args,
SelectionDAG &DAG) { SelectionDAG &DAG) {
int NumBytes = 0; int NumBytes = 0;
if (Args.size() > 6) if (Args.size() > 6)
@ -413,12 +413,12 @@ SDOperand AlphaTargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP,
Value *VAListV, SelectionDAG &DAG) { Value *VAListV, SelectionDAG &DAG) {
// vastart stores the address of the VarArgsBase and VarArgsOffset // vastart stores the address of the VarArgsBase and VarArgsOffset
SDOperand FR = DAG.getFrameIndex(VarArgsBase, MVT::i64); SDOperand FR = DAG.getFrameIndex(VarArgsBase, MVT::i64);
SDOperand S1 = DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, VAListP, SDOperand S1 = DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, VAListP,
DAG.getSrcValue(VAListV)); DAG.getSrcValue(VAListV));
SDOperand SA2 = DAG.getNode(ISD::ADD, MVT::i64, VAListP, SDOperand SA2 = DAG.getNode(ISD::ADD, MVT::i64, VAListP,
DAG.getConstant(8, MVT::i64)); DAG.getConstant(8, MVT::i64));
return DAG.getNode(ISD::TRUNCSTORE, MVT::Other, S1, return DAG.getNode(ISD::TRUNCSTORE, MVT::Other, S1,
DAG.getConstant(VarArgsOffset, MVT::i64), SA2, DAG.getConstant(VarArgsOffset, MVT::i64), SA2,
DAG.getSrcValue(VAListV, 8), DAG.getValueType(MVT::i32)); DAG.getSrcValue(VAListV, 8), DAG.getValueType(MVT::i32));
} }
@ -427,9 +427,9 @@ LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
const Type *ArgTy, SelectionDAG &DAG) { const Type *ArgTy, SelectionDAG &DAG) {
SDOperand Base = DAG.getLoad(MVT::i64, Chain, VAListP, SDOperand Base = DAG.getLoad(MVT::i64, Chain, VAListP,
DAG.getSrcValue(VAListV)); DAG.getSrcValue(VAListV));
SDOperand Tmp = DAG.getNode(ISD::ADD, MVT::i64, VAListP, SDOperand Tmp = DAG.getNode(ISD::ADD, MVT::i64, VAListP,
DAG.getConstant(8, MVT::i64)); DAG.getConstant(8, MVT::i64));
SDOperand Offset = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Base.getValue(1), SDOperand Offset = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Base.getValue(1),
Tmp, DAG.getSrcValue(VAListV, 8), MVT::i32); Tmp, DAG.getSrcValue(VAListV, 8), MVT::i32);
SDOperand DataPtr = DAG.getNode(ISD::ADD, MVT::i64, Base, Offset); SDOperand DataPtr = DAG.getNode(ISD::ADD, MVT::i64, Base, Offset);
if (ArgTy->isFloatingPoint()) if (ArgTy->isFloatingPoint())
@ -437,7 +437,7 @@ LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
//if fp && Offset < 6*8, then subtract 6*8 from DataPtr //if fp && Offset < 6*8, then subtract 6*8 from DataPtr
SDOperand FPDataPtr = DAG.getNode(ISD::SUB, MVT::i64, DataPtr, SDOperand FPDataPtr = DAG.getNode(ISD::SUB, MVT::i64, DataPtr,
DAG.getConstant(8*6, MVT::i64)); DAG.getConstant(8*6, MVT::i64));
SDOperand CC = DAG.getSetCC(ISD::SETLT, MVT::i64, SDOperand CC = DAG.getSetCC(ISD::SETLT, MVT::i64,
Offset, DAG.getConstant(8*6, MVT::i64)); Offset, DAG.getConstant(8*6, MVT::i64));
DataPtr = DAG.getNode(ISD::SELECT, MVT::i64, CC, FPDataPtr, DataPtr); DataPtr = DAG.getNode(ISD::SELECT, MVT::i64, CC, FPDataPtr, DataPtr);
} }
@ -450,13 +450,13 @@ LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
Result = DAG.getExtLoad(ISD::ZEXTLOAD, MVT::i64, Offset.getValue(1), Result = DAG.getExtLoad(ISD::ZEXTLOAD, MVT::i64, Offset.getValue(1),
DataPtr, DAG.getSrcValue(NULL), MVT::i32); DataPtr, DAG.getSrcValue(NULL), MVT::i32);
else else
Result = DAG.getLoad(getValueType(ArgTy), Offset.getValue(1), DataPtr, Result = DAG.getLoad(getValueType(ArgTy), Offset.getValue(1), DataPtr,
DAG.getSrcValue(NULL)); DAG.getSrcValue(NULL));
SDOperand NewOffset = DAG.getNode(ISD::ADD, MVT::i64, Offset, SDOperand NewOffset = DAG.getNode(ISD::ADD, MVT::i64, Offset,
DAG.getConstant(8, MVT::i64)); DAG.getConstant(8, MVT::i64));
SDOperand Update = DAG.getNode(ISD::TRUNCSTORE, MVT::Other, SDOperand Update = DAG.getNode(ISD::TRUNCSTORE, MVT::Other,
Result.getValue(1), NewOffset, Result.getValue(1), NewOffset,
Tmp, DAG.getSrcValue(VAListV, 8), Tmp, DAG.getSrcValue(VAListV, 8),
DAG.getValueType(MVT::i32)); DAG.getValueType(MVT::i32));
Result = DAG.getNode(ISD::TRUNCATE, getValueType(ArgTy), Result); Result = DAG.getNode(ISD::TRUNCATE, getValueType(ArgTy), Result);
@ -468,15 +468,15 @@ LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
SDOperand AlphaTargetLowering:: SDOperand AlphaTargetLowering::
LowerVACopy(SDOperand Chain, SDOperand SrcP, Value *SrcV, SDOperand DestP, LowerVACopy(SDOperand Chain, SDOperand SrcP, Value *SrcV, SDOperand DestP,
Value *DestV, SelectionDAG &DAG) { Value *DestV, SelectionDAG &DAG) {
SDOperand Val = DAG.getLoad(getPointerTy(), Chain, SrcP, SDOperand Val = DAG.getLoad(getPointerTy(), Chain, SrcP,
DAG.getSrcValue(SrcV)); DAG.getSrcValue(SrcV));
SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1), SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1),
Val, DestP, DAG.getSrcValue(DestV)); Val, DestP, DAG.getSrcValue(DestV));
SDOperand NP = DAG.getNode(ISD::ADD, MVT::i64, SrcP, SDOperand NP = DAG.getNode(ISD::ADD, MVT::i64, SrcP,
DAG.getConstant(8, MVT::i64)); DAG.getConstant(8, MVT::i64));
Val = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Result, NP, Val = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Result, NP,
DAG.getSrcValue(SrcV, 8), MVT::i32); DAG.getSrcValue(SrcV, 8), MVT::i32);
SDOperand NPD = DAG.getNode(ISD::ADD, MVT::i64, DestP, SDOperand NPD = DAG.getNode(ISD::ADD, MVT::i64, DestP,
DAG.getConstant(8, MVT::i64)); DAG.getConstant(8, MVT::i64));
return DAG.getNode(ISD::TRUNCSTORE, MVT::Other, Val.getValue(1), return DAG.getNode(ISD::TRUNCSTORE, MVT::Other, Val.getValue(1),
Val, NPD, DAG.getSrcValue(DestV, 8), Val, NPD, DAG.getSrcValue(DestV, 8),
@ -514,7 +514,7 @@ class AlphaISel : public SelectionDAGISel {
int max_depth; int max_depth;
public: public:
AlphaISel(TargetMachine &TM) : SelectionDAGISel(AlphaLowering), AlphaISel(TargetMachine &TM) : SelectionDAGISel(AlphaLowering),
AlphaLowering(TM) AlphaLowering(TM)
{} {}
@ -535,9 +535,9 @@ public:
if(has_sym) if(has_sym)
++count_ins; ++count_ins;
if(EnableAlphaCount) if(EnableAlphaCount)
std::cerr << "COUNT: " std::cerr << "COUNT: "
<< BB->getParent()->getFunction ()->getName() << " " << BB->getParent()->getFunction ()->getName() << " "
<< BB->getNumber() << " " << BB->getNumber() << " "
<< max_depth << " " << max_depth << " "
<< count_ins << " " << count_ins << " "
<< count_outs << "\n"; << count_outs << "\n";
@ -546,7 +546,7 @@ public:
ExprMap.clear(); ExprMap.clear();
CCInvMap.clear(); CCInvMap.clear();
} }
virtual void EmitFunctionEntryCode(Function &Fn, MachineFunction &MF); virtual void EmitFunctionEntryCode(Function &Fn, MachineFunction &MF);
unsigned SelectExpr(SDOperand N); unsigned SelectExpr(SDOperand N);
@ -1032,7 +1032,7 @@ void AlphaISel::SelectBranchCC(SDOperand N)
return; return;
} }
} else { //FP } else { //FP
//Any comparison between 2 values should be codegened as an folded //Any comparison between 2 values should be codegened as an folded
//branch, as moving CC to the integer register is very expensive //branch, as moving CC to the integer register is very expensive
//for a cmp b: c = a - b; //for a cmp b: c = a - b;
//a = b: c = 0 //a = b: c = 0
@ -1298,7 +1298,7 @@ unsigned AlphaISel::SelectExpr(SDOperand N) {
case ISD::GlobalAddress: case ISD::GlobalAddress:
AlphaLowering.restoreGP(BB); AlphaLowering.restoreGP(BB);
has_sym = true; has_sym = true;
Reg = Result = MakeReg(MVT::i64); Reg = Result = MakeReg(MVT::i64);
if (EnableAlphaLSMark) if (EnableAlphaLSMark)
@ -1559,7 +1559,7 @@ unsigned AlphaISel::SelectExpr(SDOperand N) {
switch (SetCC->getCondition()) { switch (SetCC->getCondition()) {
default: Node->dump(); assert(0 && "Unknown integer comparison!"); default: Node->dump(); assert(0 && "Unknown integer comparison!");
case ISD::SETEQ: case ISD::SETEQ:
Opc = isConst ? Alpha::CMPEQi : Alpha::CMPEQ; dir=1; break; Opc = isConst ? Alpha::CMPEQi : Alpha::CMPEQ; dir=1; break;
case ISD::SETLT: case ISD::SETLT:
Opc = isConst ? Alpha::CMPLTi : Alpha::CMPLT; dir = 1; break; Opc = isConst ? Alpha::CMPLTi : Alpha::CMPLT; dir = 1; break;
@ -1675,7 +1675,7 @@ unsigned AlphaISel::SelectExpr(SDOperand N) {
//Check operand(0) == Not //Check operand(0) == Not
if (N.getOperand(0).getOpcode() == ISD::XOR && if (N.getOperand(0).getOpcode() == ISD::XOR &&
N.getOperand(0).getOperand(1).getOpcode() == ISD::Constant && N.getOperand(0).getOperand(1).getOpcode() == ISD::Constant &&
cast<ConstantSDNode>(N.getOperand(0).getOperand(1))->getSignExtended() cast<ConstantSDNode>(N.getOperand(0).getOperand(1))->getSignExtended()
== -1) { == -1) {
switch(opcode) { switch(opcode) {
case ISD::AND: Opc = Alpha::BIC; break; case ISD::AND: Opc = Alpha::BIC; break;
@ -1730,8 +1730,8 @@ unsigned AlphaISel::SelectExpr(SDOperand N) {
case ISD::SHL: Opc = Alpha::SL; break; case ISD::SHL: Opc = Alpha::SL; break;
case ISD::SRL: Opc = Alpha::SRL; break; case ISD::SRL: Opc = Alpha::SRL; break;
case ISD::SRA: Opc = Alpha::SRA; break; case ISD::SRA: Opc = Alpha::SRA; break;
case ISD::MUL: case ISD::MUL:
Opc = isFP ? (DestType == MVT::f64 ? Alpha::MULT : Alpha::MULS) Opc = isFP ? (DestType == MVT::f64 ? Alpha::MULT : Alpha::MULS)
: Alpha::MULQ; : Alpha::MULQ;
break; break;
}; };
@ -1807,7 +1807,7 @@ unsigned AlphaISel::SelectExpr(SDOperand N) {
} }
else if((CSD = dyn_cast<ConstantSDNode>(N.getOperand(1))) && else if((CSD = dyn_cast<ConstantSDNode>(N.getOperand(1))) &&
(int64_t)CSD->getValue() >= 255 && (int64_t)CSD->getValue() >= 255 &&
(int64_t)CSD->getValue() <= 0) (int64_t)CSD->getValue() <= 0)
{ //inverted imm add/sub { //inverted imm add/sub
Opc = isAdd ? Alpha::SUBQi : Alpha::ADDQi; Opc = isAdd ? Alpha::SUBQi : Alpha::ADDQi;
Tmp1 = SelectExpr(N.getOperand(0)); Tmp1 = SelectExpr(N.getOperand(0));
@ -1903,7 +1903,7 @@ unsigned AlphaISel::SelectExpr(SDOperand N) {
} }
Tmp1 = SelectExpr(N.getOperand(0)); Tmp1 = SelectExpr(N.getOperand(0));
Tmp2 = SelectExpr(N.getOperand(1)); Tmp2 = SelectExpr(N.getOperand(1));
SDOperand Addr = SDOperand Addr =
ISelDAG->getExternalSymbol(opstr, AlphaLowering.getPointerTy()); ISelDAG->getExternalSymbol(opstr, AlphaLowering.getPointerTy());
Tmp3 = SelectExpr(Addr); Tmp3 = SelectExpr(Addr);
//set up regs explicitly (helps Reg alloc) //set up regs explicitly (helps Reg alloc)
@ -1947,7 +1947,7 @@ unsigned AlphaISel::SelectExpr(SDOperand N) {
if (SetCC && !MVT::isInteger(SetCC->getOperand(0).getValueType())) if (SetCC && !MVT::isInteger(SetCC->getOperand(0).getValueType()))
{ //FP Setcc -> Select yay! { //FP Setcc -> Select yay!
//for a cmp b: c = a - b; //for a cmp b: c = a - b;
//a = b: c = 0 //a = b: c = 0
//a < b: c < 0 //a < b: c < 0
@ -2000,7 +2000,7 @@ unsigned AlphaISel::SelectExpr(SDOperand N) {
// // Get the condition into the zero flag. // // Get the condition into the zero flag.
// BuildMI(BB, Alpha::FCMOVEQ, 3, Result).addReg(TV).addReg(FV).addReg(Tmp4); // BuildMI(BB, Alpha::FCMOVEQ, 3, Result).addReg(TV).addReg(FV).addReg(Tmp4);
return Result; return Result;
} }
} else { } else {
//FIXME: look at parent to decide if intCC can be folded, or if setCC(FP) //FIXME: look at parent to decide if intCC can be folded, or if setCC(FP)
//and can save stack use //and can save stack use
@ -2116,7 +2116,7 @@ unsigned AlphaISel::SelectExpr(SDOperand N) {
//re-get the val since we are going to mem anyway //re-get the val since we are going to mem anyway
val = (int64_t)cast<ConstantSDNode>(N)->getValue(); val = (int64_t)cast<ConstantSDNode>(N)->getValue();
MachineConstantPool *CP = BB->getParent()->getConstantPool(); MachineConstantPool *CP = BB->getParent()->getConstantPool();
ConstantUInt *C = ConstantUInt *C =
ConstantUInt::get(Type::getPrimitiveType(Type::ULongTyID) , val); ConstantUInt::get(Type::getPrimitiveType(Type::ULongTyID) , val);
unsigned CPI = CP->getConstantPoolIndex(C); unsigned CPI = CP->getConstantPoolIndex(C);
AlphaLowering.restoreGP(BB); AlphaLowering.restoreGP(BB);
@ -2317,8 +2317,8 @@ void AlphaISel::Select(SDOperand N) {
} }
int i, j, k; int i, j, k;
if (EnableAlphaLSMark) if (EnableAlphaLSMark)
getValueInfo(cast<SrcValueSDNode>(N.getOperand(3))->getValue(), getValueInfo(cast<SrcValueSDNode>(N.getOperand(3))->getValue(),
i, j, k); i, j, k);
GlobalAddressSDNode *GASD = dyn_cast<GlobalAddressSDNode>(Address); GlobalAddressSDNode *GASD = dyn_cast<GlobalAddressSDNode>(Address);

View File

@ -59,7 +59,7 @@ extern "C" {
void* CameFromOrig = (void*)*(oldsp - 2); void* CameFromOrig = (void*)*(oldsp - 2);
void* Target = JITCompilerFunction(CameFromStub); void* Target = JITCompilerFunction(CameFromStub);
//rewrite the stub to an unconditional branch //rewrite the stub to an unconditional branch
EmitBranchToAt(CameFromStub, Target, false); EmitBranchToAt(CameFromStub, Target, false);
@ -256,7 +256,7 @@ void AlphaJITInfo::relocate(void *Function, MachineRelocation *MR,
case 0x08: //LDA case 0x08: //LDA
assert(gpdistmap[make_pair(Function, MR->getConstantVal())] && assert(gpdistmap[make_pair(Function, MR->getConstantVal())] &&
"LDAg without seeing LDAHg"); "LDAg without seeing LDAHg");
idx = &GOTBase[GOToffset * 8] - idx = &GOTBase[GOToffset * 8] -
(unsigned char*)gpdistmap[make_pair(Function, MR->getConstantVal())]; (unsigned char*)gpdistmap[make_pair(Function, MR->getConstantVal())];
idx = getLower16(idx); idx = getLower16(idx);
DEBUG(std::cerr << "LDA: " << idx << "\n"); DEBUG(std::cerr << "LDA: " << idx << "\n");

View File

@ -226,7 +226,7 @@ IA64TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
// Create the frame index object for this incoming parameter... // Create the frame index object for this incoming parameter...
ArgOffset = 16 + 8 * (count - 8); ArgOffset = 16 + 8 * (count - 8);
int FI = MFI->CreateFixedObject(8, ArgOffset); int FI = MFI->CreateFixedObject(8, ArgOffset);
// Create the SelectionDAG nodes corresponding to a load // Create the SelectionDAG nodes corresponding to a load
//from this parameter //from this parameter
SDOperand FIN = DAG.getFrameIndex(FI, MVT::i64); SDOperand FIN = DAG.getFrameIndex(FI, MVT::i64);
@ -307,7 +307,7 @@ std::pair<SDOperand, SDOperand>
IA64TargetLowering::LowerCallTo(SDOperand Chain, IA64TargetLowering::LowerCallTo(SDOperand Chain,
const Type *RetTy, bool isVarArg, const Type *RetTy, bool isVarArg,
unsigned CallingConv, bool isTailCall, unsigned CallingConv, bool isTailCall,
SDOperand Callee, ArgListTy &Args, SDOperand Callee, ArgListTy &Args,
SelectionDAG &DAG) { SelectionDAG &DAG) {
MachineFunction &MF = DAG.getMachineFunction(); MachineFunction &MF = DAG.getMachineFunction();
@ -400,7 +400,7 @@ LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
"Other types should have been promoted for varargs!"); "Other types should have been promoted for varargs!");
Amt = 8; Amt = 8;
} }
Val = DAG.getNode(ISD::ADD, Val.getValueType(), Val, Val = DAG.getNode(ISD::ADD, Val.getValueType(), Val,
DAG.getConstant(Amt, Val.getValueType())); DAG.getConstant(Amt, Val.getValueType()));
Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain,
Val, VAListP, DAG.getSrcValue(VAListV)); Val, VAListP, DAG.getSrcValue(VAListV));
@ -494,22 +494,22 @@ void boothEncode(std::string inString, std::string& boothEncodedString) {
int lim=inString.size(); int lim=inString.size();
while(curpos<lim) { while(curpos<lim) {
if(inString[curpos]=='1') { // if we see a '1', look for a run of them if(inString[curpos]=='1') { // if we see a '1', look for a run of them
int runlength=0; int runlength=0;
std::string replaceString="N"; std::string replaceString="N";
// find the run length // find the run length
for(;inString[curpos+runlength]=='1';runlength++) ; for(;inString[curpos+runlength]=='1';runlength++) ;
for(int i=0; i<runlength-1; i++) for(int i=0; i<runlength-1; i++)
replaceString+="0"; replaceString+="0";
replaceString+="1"; replaceString+="1";
if(runlength>1) { if(runlength>1) {
inString.replace(curpos, runlength+1, replaceString); inString.replace(curpos, runlength+1, replaceString);
curpos+=runlength-1; curpos+=runlength-1;
} else } else
curpos++; curpos++;
} else { // a zero, we just keep chugging along } else { // a zero, we just keep chugging along
curpos++; curpos++;
} }
@ -529,7 +529,7 @@ void boothEncode(std::string inString, std::string& boothEncodedString) {
struct shiftaddblob { // this encodes stuff like (x=) "A << B [+-] C << D" struct shiftaddblob { // this encodes stuff like (x=) "A << B [+-] C << D"
unsigned firstVal; // A unsigned firstVal; // A
unsigned firstShift; // B unsigned firstShift; // B
unsigned secondVal; // C unsigned secondVal; // C
unsigned secondShift; // D unsigned secondShift; // D
bool isSub; bool isSub;
@ -555,7 +555,7 @@ unsigned lefevre(const std::string inString,
} }
std::vector<int> p,n; std::vector<int> p,n;
for(int i=0; i<=length; i++) { for(int i=0; i<=length; i++) {
if (s.c_str()[length-i]=='P') { if (s.c_str()[length-i]=='P') {
p.push_back(i); p.push_back(i);
@ -609,49 +609,49 @@ unsigned lefevre(const std::string inString,
int z=abs(int_d)-1; int z=abs(int_d)-1;
if(int_d>0) { if(int_d>0) {
for(unsigned base=0; base<retstring.size(); base++) { for(unsigned base=0; base<retstring.size(); base++) {
if( ((base+z+1) < retstring.size()) && if( ((base+z+1) < retstring.size()) &&
retstring.c_str()[base]=='P' && retstring.c_str()[base]=='P' &&
retstring.c_str()[base+z+1]=='P') retstring.c_str()[base+z+1]=='P')
{ {
// match // match
x++; x++;
retstring.replace(base, 1, "0"); retstring.replace(base, 1, "0");
retstring.replace(base+z+1, 1, "p"); retstring.replace(base+z+1, 1, "p");
} }
} }
for(unsigned base=0; base<retstring.size(); base++) { for(unsigned base=0; base<retstring.size(); base++) {
if( ((base+z+1) < retstring.size()) && if( ((base+z+1) < retstring.size()) &&
retstring.c_str()[base]=='N' && retstring.c_str()[base]=='N' &&
retstring.c_str()[base+z+1]=='N') retstring.c_str()[base+z+1]=='N')
{ {
// match // match
x++; x++;
retstring.replace(base, 1, "0"); retstring.replace(base, 1, "0");
retstring.replace(base+z+1, 1, "n"); retstring.replace(base+z+1, 1, "n");
} }
} }
} else { } else {
for(unsigned base=0; base<retstring.size(); base++) { for(unsigned base=0; base<retstring.size(); base++) {
if( ((base+z+1) < retstring.size()) && if( ((base+z+1) < retstring.size()) &&
((retstring.c_str()[base]=='P' && ((retstring.c_str()[base]=='P' &&
retstring.c_str()[base+z+1]=='N') || retstring.c_str()[base+z+1]=='N') ||
(retstring.c_str()[base]=='N' && (retstring.c_str()[base]=='N' &&
retstring.c_str()[base+z+1]=='P')) ) { retstring.c_str()[base+z+1]=='P')) ) {
// match // match
x++; x++;
if(retstring.c_str()[base]=='P') { if(retstring.c_str()[base]=='P') {
retstring.replace(base, 1, "0"); retstring.replace(base, 1, "0");
retstring.replace(base+z+1, 1, "p"); retstring.replace(base+z+1, 1, "p");
} else { // retstring[base]=='N' } else { // retstring[base]=='N'
retstring.replace(base, 1, "0"); retstring.replace(base, 1, "0");
retstring.replace(base+z+1, 1, "n"); retstring.replace(base+z+1, 1, "n");
} }
} }
} }
} }
@ -660,11 +660,11 @@ unsigned lefevre(const std::string inString,
t = retstring; t = retstring;
c = int_d; // tofix c = int_d; // tofix
} }
} d.pop_back(); // hmm } d.pop_back(); // hmm
u = t; u = t;
for(unsigned i=0; i<t.length(); i++) { for(unsigned i=0; i<t.length(); i++) {
if(t.c_str()[i]=='p' || t.c_str()[i]=='n') if(t.c_str()[i]=='p' || t.c_str()[i]=='n')
t.replace(i, 1, "0"); t.replace(i, 1, "0");
@ -684,7 +684,7 @@ unsigned lefevre(const std::string inString,
c=-c; c=-c;
} else } else
f=false; f=false;
int pos=0; int pos=0;
while(u[pos]=='0') while(u[pos]=='0')
pos++; pos++;
@ -699,9 +699,9 @@ unsigned lefevre(const std::string inString,
bool isN=(u[p]=='N'); bool isN=(u[p]=='N');
if(isP) if(isP)
u.replace(p, 1, "N"); u.replace(p, 1, "N");
if(isN) if(isN)
u.replace(p, 1, "P"); u.replace(p, 1, "P");
} }
} }
@ -710,7 +710,7 @@ unsigned lefevre(const std::string inString,
int i = lefevre(u, ops); int i = lefevre(u, ops);
shiftaddblob blob; shiftaddblob blob;
blob.firstVal=i; blob.firstShift=c; blob.firstVal=i; blob.firstShift=c;
blob.isSub=f; blob.isSub=f;
blob.secondVal=i; blob.secondShift=0; blob.secondVal=i; blob.secondShift=0;
@ -731,9 +731,9 @@ unsigned lefevre(const std::string inString,
bool isN=(t.c_str()[p]=='N'); bool isN=(t.c_str()[p]=='N');
if(isP) if(isP)
t.replace(p, 1, "N"); t.replace(p, 1, "N");
if(isN) if(isN)
t.replace(p, 1, "P"); t.replace(p, 1, "P");
} }
} }
@ -764,7 +764,7 @@ unsigned lefevre(const std::string inString,
break; break;
//assert //assert
} }
ops.push_back(blob); ops.push_back(blob);
return ops.size(); return ops.size();
} }
@ -808,7 +808,7 @@ SDOperand ISel::BuildConstmulSequence(SDOperand N) {
assert(ops.size() < 80 && "constmul code has gone haywire\n"); assert(ops.size() < 80 && "constmul code has gone haywire\n");
SDOperand results[80]; // temporary results (of adds/subs of shifts) SDOperand results[80]; // temporary results (of adds/subs of shifts)
// now turn 'ops' into DAG bits // now turn 'ops' into DAG bits
for(unsigned i=0; i<ops.size(); i++) { for(unsigned i=0; i<ops.size(); i++) {
SDOperand amt = ISelDAG->getConstant(ops[i].firstShift, MVT::i64); SDOperand amt = ISelDAG->getConstant(ops[i].firstShift, MVT::i64);
@ -830,11 +830,11 @@ SDOperand ISel::BuildConstmulSequence(SDOperand N) {
if(preliminaryShift) { if(preliminaryShift) {
SDOperand finalshift = ISelDAG->getConstant(preliminaryShift, MVT::i64); SDOperand finalshift = ISelDAG->getConstant(preliminaryShift, MVT::i64);
shiftedresult = ISelDAG->getNode(ISD::SHL, MVT::i64, shiftedresult = ISelDAG->getNode(ISD::SHL, MVT::i64,
results[ops.size()-1], finalshift); results[ops.size()-1], finalshift);
} else { // there was no preliminary divide-by-power-of-2 required } else { // there was no preliminary divide-by-power-of-2 required
shiftedresult = results[ops.size()-1]; shiftedresult = results[ops.size()-1];
} }
SDOperand finalresult; SDOperand finalresult;
if(flippedSign) { // if we were multiplying by a negative constant: if(flippedSign) { // if we were multiplying by a negative constant:
SDOperand zero = ISelDAG->getConstant(0, MVT::i64); SDOperand zero = ISelDAG->getConstant(0, MVT::i64);
@ -843,8 +843,8 @@ SDOperand ISel::BuildConstmulSequence(SDOperand N) {
} else { // there was no preliminary multiply by -1 required } else { // there was no preliminary multiply by -1 required
finalresult = shiftedresult; finalresult = shiftedresult;
} }
return finalresult; return finalresult;
} }
/// ExactLog2 - This function solves for (Val == 1 << (N-1)) and returns N. It /// ExactLog2 - This function solves for (Val == 1 << (N-1)) and returns N. It
@ -1098,7 +1098,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
.addReg(Tmp1); .addReg(Tmp1);
break; break;
} }
return Result; return Result;
} }
@ -1316,7 +1316,7 @@ assert(0 && "hmm, ISD::SIGN_EXTEND: shouldn't ever be reached. bad luck!\n");
Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
int shl_amt = CSD->getValue(); int shl_amt = CSD->getValue();
Tmp3 = SelectExpr(N.getOperand(1)); Tmp3 = SelectExpr(N.getOperand(1));
BuildMI(BB, IA64::SHLADD, 3, Result) BuildMI(BB, IA64::SHLADD, 3, Result)
.addReg(Tmp1).addImm(shl_amt).addReg(Tmp3); .addReg(Tmp1).addImm(shl_amt).addReg(Tmp3);
return Result; // early exit return Result; // early exit
@ -1344,21 +1344,21 @@ assert(0 && "hmm, ISD::SIGN_EXTEND: shouldn't ever be reached. bad luck!\n");
if(DestType != MVT::f64) { // TODO: speed! if(DestType != MVT::f64) { // TODO: speed!
if(N.getOperand(1).getOpcode() != ISD::Constant) { // if not a const mul if(N.getOperand(1).getOpcode() != ISD::Constant) { // if not a const mul
// boring old integer multiply with xma // boring old integer multiply with xma
Tmp1 = SelectExpr(N.getOperand(0)); Tmp1 = SelectExpr(N.getOperand(0));
Tmp2 = SelectExpr(N.getOperand(1)); Tmp2 = SelectExpr(N.getOperand(1));
unsigned TempFR1=MakeReg(MVT::f64); unsigned TempFR1=MakeReg(MVT::f64);
unsigned TempFR2=MakeReg(MVT::f64); unsigned TempFR2=MakeReg(MVT::f64);
unsigned TempFR3=MakeReg(MVT::f64); unsigned TempFR3=MakeReg(MVT::f64);
BuildMI(BB, IA64::SETFSIG, 1, TempFR1).addReg(Tmp1); BuildMI(BB, IA64::SETFSIG, 1, TempFR1).addReg(Tmp1);
BuildMI(BB, IA64::SETFSIG, 1, TempFR2).addReg(Tmp2); BuildMI(BB, IA64::SETFSIG, 1, TempFR2).addReg(Tmp2);
BuildMI(BB, IA64::XMAL, 1, TempFR3).addReg(TempFR1).addReg(TempFR2) BuildMI(BB, IA64::XMAL, 1, TempFR3).addReg(TempFR1).addReg(TempFR2)
.addReg(IA64::F0); .addReg(IA64::F0);
BuildMI(BB, IA64::GETFSIG, 1, Result).addReg(TempFR3); BuildMI(BB, IA64::GETFSIG, 1, Result).addReg(TempFR3);
return Result; // early exit return Result; // early exit
} else { // we are multiplying by an integer constant! yay } else { // we are multiplying by an integer constant! yay
return Reg = SelectExpr(BuildConstmulSequence(N)); // avert your eyes! return Reg = SelectExpr(BuildConstmulSequence(N)); // avert your eyes!
} }
} }
else { // floating point multiply else { // floating point multiply
@ -1799,7 +1799,7 @@ pC = pA OR pB
unsigned ModulusResult = MakeReg(MVT::f64); unsigned ModulusResult = MakeReg(MVT::f64);
unsigned TmpF = MakeReg(MVT::f64); unsigned TmpF = MakeReg(MVT::f64);
unsigned TmpI = MakeReg(MVT::i64); unsigned TmpI = MakeReg(MVT::i64);
BuildMI(BB, IA64::SUB, 2, TmpI).addReg(IA64::r0).addReg(Tmp2); BuildMI(BB, IA64::SUB, 2, TmpI).addReg(IA64::r0).addReg(Tmp2);
BuildMI(BB, IA64::SETFSIG, 1, TmpF).addReg(TmpI); BuildMI(BB, IA64::SETFSIG, 1, TmpF).addReg(TmpI);
BuildMI(BB, IA64::XMAL, 3, ModulusResult) BuildMI(BB, IA64::XMAL, 3, ModulusResult)
@ -1843,7 +1843,7 @@ pC = pA OR pB
Tmp2 = SelectExpr(N.getOperand(1)); Tmp2 = SelectExpr(N.getOperand(1));
} else // not comparing against a constant } else // not comparing against a constant
Tmp2 = SelectExpr(N.getOperand(1)); Tmp2 = SelectExpr(N.getOperand(1));
switch (SetCC->getCondition()) { switch (SetCC->getCondition()) {
default: assert(0 && "Unknown integer comparison!"); default: assert(0 && "Unknown integer comparison!");
case ISD::SETEQ: case ISD::SETEQ:
@ -1956,7 +1956,7 @@ pC = pA OR pB
case MVT::i16: Opc = IA64::LD2; break; case MVT::i16: Opc = IA64::LD2; break;
case MVT::i32: Opc = IA64::LD4; break; case MVT::i32: Opc = IA64::LD4; break;
case MVT::i64: Opc = IA64::LD8; break; case MVT::i64: Opc = IA64::LD8; break;
case MVT::f32: Opc = IA64::LDF4; break; case MVT::f32: Opc = IA64::LDF4; break;
case MVT::f64: Opc = IA64::LDF8; break; case MVT::f64: Opc = IA64::LDF8; break;
} }
@ -2037,7 +2037,7 @@ pC = pA OR pB
BuildMI(BB, Opc, 1, dummy).addReg(Tmp2); BuildMI(BB, Opc, 1, dummy).addReg(Tmp2);
// we compare to 0. true? 0. false? 1. // we compare to 0. true? 0. false? 1.
BuildMI(BB, IA64::CMPNE, 2, Result).addReg(dummy).addReg(IA64::r0); BuildMI(BB, IA64::CMPNE, 2, Result).addReg(dummy).addReg(IA64::r0);
} }
} }
return Result; return Result;
@ -2114,7 +2114,7 @@ pC = pA OR pB
for (int i = 8, e = argvregs.size(); i < e; ++i) for (int i = 8, e = argvregs.size(); i < e; ++i)
{ {
unsigned tempAddr = MakeReg(MVT::i64); unsigned tempAddr = MakeReg(MVT::i64);
switch(N.getOperand(i+2).getValueType()) { switch(N.getOperand(i+2).getValueType()) {
default: default:
Node->dump(); Node->dump();
@ -2157,7 +2157,7 @@ pC = pA OR pB
} }
else { // otherwise we need to get the function descriptor else { // otherwise we need to get the function descriptor
// load the branch target (function)'s entry point and // load the branch target (function)'s entry point and
// GP, then branch // GP, then branch
Tmp1 = SelectExpr(N.getOperand(1)); Tmp1 = SelectExpr(N.getOperand(1));
unsigned targetEntryPoint=MakeReg(MVT::i64); unsigned targetEntryPoint=MakeReg(MVT::i64);
@ -2355,7 +2355,7 @@ void ISel::Select(SDOperand N) {
case MVT::i16: Opc = IA64::ST2; break; case MVT::i16: Opc = IA64::ST2; break;
case MVT::i32: Opc = IA64::ST4; break; case MVT::i32: Opc = IA64::ST4; break;
case MVT::i64: Opc = IA64::ST8; break; case MVT::i64: Opc = IA64::ST8; break;
case MVT::f32: Opc = IA64::STF4; break; case MVT::f32: Opc = IA64::STF4; break;
case MVT::f64: Opc = IA64::STF8; break; case MVT::f64: Opc = IA64::STF8; break;
} }
@ -2394,7 +2394,7 @@ void ISel::Select(SDOperand N) {
} else if(N.getOperand(2).getOpcode() == ISD::FrameIndex) { } else if(N.getOperand(2).getOpcode() == ISD::FrameIndex) {
// FIXME? (what about bools?) // FIXME? (what about bools?)
unsigned dummy = MakeReg(MVT::i64); unsigned dummy = MakeReg(MVT::i64);
BuildMI(BB, IA64::MOV, 1, dummy) BuildMI(BB, IA64::MOV, 1, dummy)
.addFrameIndex(cast<FrameIndexSDNode>(N.getOperand(2))->getIndex()); .addFrameIndex(cast<FrameIndexSDNode>(N.getOperand(2))->getIndex());

View File

@ -201,7 +201,7 @@ int PPC32CodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) {
case PPC::LIS: case PPC::LIS:
if (isExternal) if (isExternal)
Reloc = PPC::reloc_absolute_ptr_high; // Pointer to stub Reloc = PPC::reloc_absolute_ptr_high; // Pointer to stub
else else
Reloc = PPC::reloc_absolute_high; // Pointer to symbol Reloc = PPC::reloc_absolute_high; // Pointer to symbol
break; break;
case PPC::LA: case PPC::LA:
@ -221,7 +221,7 @@ int PPC32CodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) {
case PPC::STFD: case PPC::STFD:
if (isExternal) if (isExternal)
Reloc = PPC::reloc_absolute_ptr_low; Reloc = PPC::reloc_absolute_ptr_low;
else else
Reloc = PPC::reloc_absolute_low; Reloc = PPC::reloc_absolute_low;
break; break;
} }

View File

@ -77,7 +77,7 @@ namespace {
setOperationAction(ISD::FSQRT, MVT::f64, Expand); setOperationAction(ISD::FSQRT, MVT::f64, Expand);
setOperationAction(ISD::FSQRT, MVT::f32, Expand); setOperationAction(ISD::FSQRT, MVT::f32, Expand);
} }
//PowerPC does not have CTPOP or CTTZ //PowerPC does not have CTPOP or CTTZ
setOperationAction(ISD::CTPOP, MVT::i32 , Expand); setOperationAction(ISD::CTPOP, MVT::i32 , Expand);
setOperationAction(ISD::CTTZ , MVT::i32 , Expand); setOperationAction(ISD::CTTZ , MVT::i32 , Expand);
@ -103,11 +103,11 @@ namespace {
virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP, virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP,
Value *VAListV, SelectionDAG &DAG); Value *VAListV, SelectionDAG &DAG);
virtual std::pair<SDOperand,SDOperand> virtual std::pair<SDOperand,SDOperand>
LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
const Type *ArgTy, SelectionDAG &DAG); const Type *ArgTy, SelectionDAG &DAG);
virtual std::pair<SDOperand, SDOperand> virtual std::pair<SDOperand, SDOperand>
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
SelectionDAG &DAG); SelectionDAG &DAG);
@ -288,7 +288,7 @@ PPC32TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
std::pair<SDOperand, SDOperand> std::pair<SDOperand, SDOperand>
PPC32TargetLowering::LowerCallTo(SDOperand Chain, PPC32TargetLowering::LowerCallTo(SDOperand Chain,
const Type *RetTy, bool isVarArg, const Type *RetTy, bool isVarArg,
unsigned CallingConv, bool isTailCall, unsigned CallingConv, bool isTailCall,
SDOperand Callee, ArgListTy &Args, SDOperand Callee, ArgListTy &Args,
SelectionDAG &DAG) { SelectionDAG &DAG) {
// args_to_use will accumulate outgoing args for the ISD::CALL case in // args_to_use will accumulate outgoing args for the ISD::CALL case in
@ -992,7 +992,7 @@ void ISel::MoveCRtoGPR(unsigned CCReg, bool Inv, unsigned Idx, unsigned Result){
bool ISel::SelectBitfieldInsert(SDOperand OR, unsigned Result) { bool ISel::SelectBitfieldInsert(SDOperand OR, unsigned Result) {
bool IsRotate = false; bool IsRotate = false;
unsigned TgtMask = 0xFFFFFFFF, InsMask = 0xFFFFFFFF, Amount = 0; unsigned TgtMask = 0xFFFFFFFF, InsMask = 0xFFFFFFFF, Amount = 0;
SDOperand Op0 = OR.getOperand(0); SDOperand Op0 = OR.getOperand(0);
SDOperand Op1 = OR.getOperand(1); SDOperand Op1 = OR.getOperand(1);
@ -1046,21 +1046,21 @@ bool ISel::SelectBitfieldInsert(SDOperand OR, unsigned Result) {
// constant as its input, make that the inserted value so that we can combine // constant as its input, make that the inserted value so that we can combine
// the shift into the rotate part of the rlwimi instruction // the shift into the rotate part of the rlwimi instruction
if (Op0Opc == ISD::AND && Op1Opc == ISD::AND) { if (Op0Opc == ISD::AND && Op1Opc == ISD::AND) {
if (Op1.getOperand(0).getOpcode() == ISD::SHL || if (Op1.getOperand(0).getOpcode() == ISD::SHL ||
Op1.getOperand(0).getOpcode() == ISD::SRL) { Op1.getOperand(0).getOpcode() == ISD::SRL) {
if (ConstantSDNode *CN = if (ConstantSDNode *CN =
dyn_cast<ConstantSDNode>(Op1.getOperand(0).getOperand(1).Val)) { dyn_cast<ConstantSDNode>(Op1.getOperand(0).getOperand(1).Val)) {
Amount = Op1.getOperand(0).getOpcode() == ISD::SHL ? Amount = Op1.getOperand(0).getOpcode() == ISD::SHL ?
CN->getValue() : 32 - CN->getValue(); CN->getValue() : 32 - CN->getValue();
Tmp3 = SelectExpr(Op1.getOperand(0).getOperand(0)); Tmp3 = SelectExpr(Op1.getOperand(0).getOperand(0));
} }
} else if (Op0.getOperand(0).getOpcode() == ISD::SHL || } else if (Op0.getOperand(0).getOpcode() == ISD::SHL ||
Op0.getOperand(0).getOpcode() == ISD::SRL) { Op0.getOperand(0).getOpcode() == ISD::SRL) {
if (ConstantSDNode *CN = if (ConstantSDNode *CN =
dyn_cast<ConstantSDNode>(Op0.getOperand(0).getOperand(1).Val)) { dyn_cast<ConstantSDNode>(Op0.getOperand(0).getOperand(1).Val)) {
std::swap(Op0, Op1); std::swap(Op0, Op1);
std::swap(TgtMask, InsMask); std::swap(TgtMask, InsMask);
Amount = Op1.getOperand(0).getOpcode() == ISD::SHL ? Amount = Op1.getOperand(0).getOpcode() == ISD::SHL ?
CN->getValue() : 32 - CN->getValue(); CN->getValue() : 32 - CN->getValue();
Tmp3 = SelectExpr(Op1.getOperand(0).getOperand(0)); Tmp3 = SelectExpr(Op1.getOperand(0).getOperand(0));
} }
@ -1878,7 +1878,7 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
return SelectExpr(BuildSDIVSequence(N)); return SelectExpr(BuildSDIVSequence(N));
else else
return SelectExpr(BuildUDIVSequence(N)); return SelectExpr(BuildUDIVSequence(N));
} }
Tmp1 = SelectExpr(N.getOperand(0)); Tmp1 = SelectExpr(N.getOperand(0));
Tmp2 = SelectExpr(N.getOperand(1)); Tmp2 = SelectExpr(N.getOperand(1));
switch (DestType) { switch (DestType) {

View File

@ -92,7 +92,7 @@ namespace {
if (OpcodeToReplace == PPC::COND_BRANCH) { if (OpcodeToReplace == PPC::COND_BRANCH) {
MachineBasicBlock::iterator MBBJ = MBBI; MachineBasicBlock::iterator MBBJ = MBBI;
++MBBJ; ++MBBJ;
// condbranch operands: // condbranch operands:
// 0. CR0 register // 0. CR0 register
// 1. bc opcode // 1. bc opcode

View File

@ -136,7 +136,7 @@ void PowerPCJITInfo::addPassesToJITCompile(FunctionPassManager &PM) {
PICEnabled = false; PICEnabled = false;
bool LP64 = (0 != dynamic_cast<PPC64TargetMachine *>(&TM)); bool LP64 = (0 != dynamic_cast<PPC64TargetMachine *>(&TM));
if (EnablePPCLSR) { if (EnablePPCLSR) {
PM.add(createLoopStrengthReducePass()); PM.add(createLoopStrengthReducePass());
PM.add(createCFGSimplificationPass()); PM.add(createCFGSimplificationPass());

View File

@ -53,19 +53,19 @@ FunctionPass *llvm::createSparcV8FPMoverPass (TargetMachine &tm) {
return new FPMover (tm); return new FPMover (tm);
} }
static void doubleToSingleRegPair(unsigned doubleReg, unsigned &singleReg1, static void doubleToSingleRegPair(unsigned doubleReg, unsigned &singleReg1,
unsigned &singleReg2) { unsigned &singleReg2) {
const unsigned EvenHalvesOfPairs[] = { const unsigned EvenHalvesOfPairs[] = {
V8::F0, V8::F2, V8::F4, V8::F6, V8::F8, V8::F10, V8::F12, V8::F14, V8::F0, V8::F2, V8::F4, V8::F6, V8::F8, V8::F10, V8::F12, V8::F14,
V8::F16, V8::F18, V8::F20, V8::F22, V8::F24, V8::F26, V8::F28, V8::F30 V8::F16, V8::F18, V8::F20, V8::F22, V8::F24, V8::F26, V8::F28, V8::F30
}; };
const unsigned OddHalvesOfPairs[] = { const unsigned OddHalvesOfPairs[] = {
V8::F1, V8::F3, V8::F5, V8::F7, V8::F9, V8::F11, V8::F13, V8::F15, V8::F1, V8::F3, V8::F5, V8::F7, V8::F9, V8::F11, V8::F13, V8::F15,
V8::F17, V8::F19, V8::F21, V8::F23, V8::F25, V8::F27, V8::F29, V8::F31 V8::F17, V8::F19, V8::F21, V8::F23, V8::F25, V8::F27, V8::F29, V8::F31
}; };
const unsigned DoubleRegsInOrder[] = { const unsigned DoubleRegsInOrder[] = {
V8::D0, V8::D1, V8::D2, V8::D3, V8::D4, V8::D5, V8::D6, V8::D7, V8::D8, V8::D0, V8::D1, V8::D2, V8::D3, V8::D4, V8::D5, V8::D6, V8::D7, V8::D8,
V8::D9, V8::D10, V8::D11, V8::D12, V8::D13, V8::D14, V8::D15 V8::D9, V8::D10, V8::D11, V8::D12, V8::D13, V8::D14, V8::D15
}; };
for (unsigned i = 0; i < sizeof(DoubleRegsInOrder)/sizeof(unsigned); ++i) for (unsigned i = 0; i < sizeof(DoubleRegsInOrder)/sizeof(unsigned); ++i)
if (DoubleRegsInOrder[i] == doubleReg) { if (DoubleRegsInOrder[i] == doubleReg) {

View File

@ -119,7 +119,7 @@ static unsigned AddLiveIn(MachineFunction &MF, unsigned PReg,
std::vector<SDOperand> std::vector<SDOperand>
V8TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) V8TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG)
{ {
static const unsigned IncomingArgRegs[] = static const unsigned IncomingArgRegs[] =
{ V8::I0, V8::I1, V8::I2, V8::I3, V8::I4, V8::I5 }; { V8::I0, V8::I1, V8::I2, V8::I3, V8::I4, V8::I5 };
std::vector<SDOperand> ArgValues; std::vector<SDOperand> ArgValues;
@ -154,8 +154,8 @@ V8TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG)
case MVT::i8: case MVT::i8:
case MVT::i16: case MVT::i16:
case MVT::i32: case MVT::i32:
argt = DAG.getCopyFromReg(AddLiveIn(MF, IncomingArgRegs[ArgNo], argt = DAG.getCopyFromReg(AddLiveIn(MF, IncomingArgRegs[ArgNo],
getRegClassFor(MVT::i32)), getRegClassFor(MVT::i32)),
VT, DAG.getRoot()); VT, DAG.getRoot());
if (VT != MVT::i32) if (VT != MVT::i32)
argt = DAG.getNode(ISD::TRUNCATE, VT, argt); argt = DAG.getNode(ISD::TRUNCATE, VT, argt);
@ -198,7 +198,7 @@ std::pair<SDOperand, SDOperand>
V8TargetLowering::LowerCallTo(SDOperand Chain, V8TargetLowering::LowerCallTo(SDOperand Chain,
const Type *RetTy, bool isVarArg, const Type *RetTy, bool isVarArg,
unsigned CallingConv, bool isTailCall, unsigned CallingConv, bool isTailCall,
SDOperand Callee, ArgListTy &Args, SDOperand Callee, ArgListTy &Args,
SelectionDAG &DAG) { SelectionDAG &DAG) {
//FIXME //FIXME
return std::make_pair(Chain, Chain); return std::make_pair(Chain, Chain);
@ -243,7 +243,7 @@ public:
// Clear state used for selection. // Clear state used for selection.
ExprMap.clear(); ExprMap.clear();
} }
virtual void EmitFunctionEntryCode(Function &Fn, MachineFunction &MF); virtual void EmitFunctionEntryCode(Function &Fn, MachineFunction &MF);
unsigned SelectExpr(SDOperand N); unsigned SelectExpr(SDOperand N);
@ -347,7 +347,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
case MVT::f64: Opc = V8::LDFSRrr; case MVT::f64: Opc = V8::LDFSRrr;
case MVT::f32: Opc = V8::LDDFrr; case MVT::f32: Opc = V8::LDDFrr;
default: default:
Node->dump(); Node->dump();
assert(0 && "Bad type!"); assert(0 && "Bad type!");
break; break;
} }
@ -374,7 +374,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
SDOperand Chain = N.getOperand(0); SDOperand Chain = N.getOperand(0);
Select(Chain); Select(Chain);
unsigned r = dyn_cast<RegSDNode>(Node)->getReg(); unsigned r = dyn_cast<RegSDNode>(Node)->getReg();
BuildMI(BB, V8::ORrr, 2, Result).addReg(r).addReg(V8::G0); BuildMI(BB, V8::ORrr, 2, Result).addReg(r).addReg(V8::G0);
return Result; return Result;
} }
@ -411,7 +411,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
Tmp2 = SelectExpr(N.getOperand(1)); Tmp2 = SelectExpr(N.getOperand(1));
BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
return Result; return Result;
} }
return 0; return 0;
} }
@ -488,7 +488,7 @@ void ISel::Select(SDOperand N) {
Tmp1 = SelectExpr(Value); Tmp1 = SelectExpr(Value);
Tmp2 = SelectExpr(Address); Tmp2 = SelectExpr(Address);
unsigned VT = opcode == ISD::STORE ? unsigned VT = opcode == ISD::STORE ?
Value.getValueType() : cast<VTSDNode>(Node->getOperand(4))->getVT(); Value.getValueType() : cast<VTSDNode>(Node->getOperand(4))->getVT();
switch(VT) { switch(VT) {
default: assert(0 && "unknown Type in store"); default: assert(0 && "unknown Type in store");

View File

@ -672,14 +672,14 @@ MarkSuccessorsReady(SchedulingManager& S, const SchedGraphNode* node)
&& ! S.schedPrio.nodeIsReady(*SI)) && ! S.schedPrio.nodeIsReady(*SI))
{ {
// successor not scheduled and not marked ready; check *its* preds. // successor not scheduled and not marked ready; check *its* preds.
bool succIsReady = true; bool succIsReady = true;
for (sg_pred_const_iterator P=pred_begin(*SI); P != pred_end(*SI); ++P) for (sg_pred_const_iterator P=pred_begin(*SI); P != pred_end(*SI); ++P)
if (! (*P)->isDummyNode() && ! S.isScheduled(*P)) { if (! (*P)->isDummyNode() && ! S.isScheduled(*P)) {
succIsReady = false; succIsReady = false;
break; break;
} }
if (succIsReady) // add the successor to the ready list if (succIsReady) // add the successor to the ready list
S.schedPrio.insertReady(*SI); S.schedPrio.insertReady(*SI);
} }
@ -828,7 +828,7 @@ FindSlotChoices(SchedulingManager& S,
S.addChoiceToSlot(s, S.getChoice(i)); S.addChoiceToSlot(s, S.getChoice(i));
noSlotFound = false; noSlotFound = false;
} }
// No slot before `delayedNodeSlot' was found for this opCode // No slot before `delayedNodeSlot' was found for this opCode
// Use a later slot, and allow some delay slots to fall in // Use a later slot, and allow some delay slots to fall in
// the next cycle. // the next cycle.
@ -838,9 +838,9 @@ FindSlotChoices(SchedulingManager& S,
S.addChoiceToSlot(s, S.getChoice(i)); S.addChoiceToSlot(s, S.getChoice(i));
break; break;
} }
assert(s < S.nslots && "No feasible slot for instruction?"); assert(s < S.nslots && "No feasible slot for instruction?");
highestSlotUsed = std::max(highestSlotUsed, (int) s); highestSlotUsed = std::max(highestSlotUsed, (int) s);
} }
@ -867,7 +867,7 @@ FindSlotChoices(SchedulingManager& S,
const SchedGraphNode* breakingNode=S.getChoice(indexForBreakingNode); const SchedGraphNode* breakingNode=S.getChoice(indexForBreakingNode);
unsigned breakingSlot = INT_MAX; unsigned breakingSlot = INT_MAX;
unsigned int nslotsToUse = S.nslots; unsigned int nslotsToUse = S.nslots;
// Find the last possible slot for this instruction. // Find the last possible slot for this instruction.
for (int s = S.nslots-1; s >= (int) startSlot; s--) for (int s = S.nslots-1; s >= (int) startSlot; s--)
if (S.schedInfo.instrCanUseSlot(breakingNode->getOpcode(), s)) { if (S.schedInfo.instrCanUseSlot(breakingNode->getOpcode(), s)) {
@ -884,7 +884,7 @@ FindSlotChoices(SchedulingManager& S,
i < S.getNumChoices() && i < indexForBreakingNode; i++) i < S.getNumChoices() && i < indexForBreakingNode; i++)
{ {
MachineOpCode opCode =S.getChoice(i)->getOpcode(); MachineOpCode opCode =S.getChoice(i)->getOpcode();
// If a higher priority instruction cannot be assigned to // If a higher priority instruction cannot be assigned to
// any earlier slots, don't schedule the breaking instruction. // any earlier slots, don't schedule the breaking instruction.
// //
@ -896,10 +896,10 @@ FindSlotChoices(SchedulingManager& S,
foundLowerSlot = true; foundLowerSlot = true;
nslotsToUse = breakingSlot; // RESETS LOOP UPPER BOUND! nslotsToUse = breakingSlot; // RESETS LOOP UPPER BOUND!
} }
S.addChoiceToSlot(s, S.getChoice(i)); S.addChoiceToSlot(s, S.getChoice(i));
} }
if (!foundLowerSlot) if (!foundLowerSlot)
breakingSlot = INT_MAX; // disable breaking instr breakingSlot = INT_MAX; // disable breaking instr
} }
@ -912,7 +912,7 @@ FindSlotChoices(SchedulingManager& S,
nslotsToUse = breakingSlot; nslotsToUse = breakingSlot;
} else } else
nslotsToUse = S.nslots; nslotsToUse = S.nslots;
// For lower priority instructions than the one that breaks the // For lower priority instructions than the one that breaks the
// group, only assign them to slots lower than the breaking slot. // group, only assign them to slots lower than the breaking slot.
// Otherwise, just ignore the instruction. // Otherwise, just ignore the instruction.
@ -1198,7 +1198,7 @@ static void ReplaceNopsWithUsefulInstr(SchedulingManager& S,
sdelayNodeVec.push_back(graph->getGraphNodeForInstr(MBBI)); sdelayNodeVec.push_back(graph->getGraphNodeForInstr(MBBI));
else { else {
nopNodeVec.push_back(graph->getGraphNodeForInstr(MBBI)); nopNodeVec.push_back(graph->getGraphNodeForInstr(MBBI));
//remove the MI from the Machine Code For Instruction //remove the MI from the Machine Code For Instruction
const TerminatorInst *TI = MBB.getBasicBlock()->getTerminator(); const TerminatorInst *TI = MBB.getBasicBlock()->getTerminator();
MachineCodeForInstruction& llvmMvec = MachineCodeForInstruction& llvmMvec =
@ -1350,7 +1350,7 @@ DelaySlotInfo::scheduleDelayedNode(SchedulingManager& S)
nextTime++; nextTime++;
} }
} while (S.isched.getInstr(nextSlot, nextTime) != NULL); } while (S.isched.getInstr(nextSlot, nextTime) != NULL);
S.scheduleInstr(delayNodeVec[i], nextSlot, nextTime); S.scheduleInstr(delayNodeVec[i], nextSlot, nextTime);
break; break;
} }
@ -1457,7 +1457,7 @@ namespace {
bool InstructionSchedulingWithSSA::runOnFunction(Function &F) bool InstructionSchedulingWithSSA::runOnFunction(Function &F)
{ {
SchedGraphSet graphSet(&F, target); SchedGraphSet graphSet(&F, target);
if (SchedDebugLevel >= Sched_PrintSchedGraphs) { if (SchedDebugLevel >= Sched_PrintSchedGraphs) {
std::cerr << "\n*** SCHEDULING GRAPHS FOR INSTRUCTION SCHEDULING\n"; std::cerr << "\n*** SCHEDULING GRAPHS FOR INSTRUCTION SCHEDULING\n";

View File

@ -365,7 +365,7 @@ void SchedGraph::addMachineRegEdges(RegToRefVecMap& regToRefVecMap,
new SchedGraphEdge(prevNode, node, regNum, new SchedGraphEdge(prevNode, node, regNum,
SchedGraphEdge::AntiDep); SchedGraphEdge::AntiDep);
} }
if (prevIsDef) if (prevIsDef)
if (!isDef || isDefAndUse) if (!isDef || isDefAndUse)
new SchedGraphEdge(prevNode, node, regNum, new SchedGraphEdge(prevNode, node, regNum,
@ -646,7 +646,7 @@ void SchedGraph::buildGraph(const TargetMachine& target) {
this->addMachineRegEdges(regToRefVecMap, target); this->addMachineRegEdges(regToRefVecMap, target);
// Finally, add edges from the dummy root and to dummy leaf // Finally, add edges from the dummy root and to dummy leaf
this->addDummyEdges(); this->addDummyEdges();
} }
@ -691,13 +691,13 @@ void SchedGraphEdge::print(std::ostream &os) const {
<< sink->getNodeId() << "] : "; << sink->getNodeId() << "] : ";
switch(depType) { switch(depType) {
case SchedGraphEdge::CtrlDep: case SchedGraphEdge::CtrlDep:
os<< "Control Dep"; os<< "Control Dep";
break; break;
case SchedGraphEdge::ValueDep: case SchedGraphEdge::ValueDep:
os<< "Reg Value " << *val; os<< "Reg Value " << *val;
break; break;
case SchedGraphEdge::MemoryDep: case SchedGraphEdge::MemoryDep:
os<< "Memory Dep"; os<< "Memory Dep";
break; break;
case SchedGraphEdge::MachineRegister: case SchedGraphEdge::MachineRegister:

View File

@ -173,8 +173,8 @@ void SchedGraphCommon::eraseOutgoingEdges(SchedGraphNodeCommon* node,
void SchedGraphCommon::eraseIncidentEdges(SchedGraphNodeCommon* node, void SchedGraphCommon::eraseIncidentEdges(SchedGraphNodeCommon* node,
bool addDummyEdges) { bool addDummyEdges) {
this->eraseIncomingEdges(node, addDummyEdges); this->eraseIncomingEdges(node, addDummyEdges);
this->eraseOutgoingEdges(node, addDummyEdges); this->eraseOutgoingEdges(node, addDummyEdges);
} }
} // End llvm namespace } // End llvm namespace

View File

@ -173,7 +173,7 @@ SchedPriorities::chooseByRule2(std::vector<candIndex>& mcands) {
inline int inline int
SchedPriorities::chooseByRule3(std::vector<candIndex>& mcands) { SchedPriorities::chooseByRule3(std::vector<candIndex>& mcands) {
assert(mcands.size() >= 1 && "Should have at least one candidate here."); assert(mcands.size() >= 1 && "Should have at least one candidate here.");
int maxUses = candsAsHeap.getNode(mcands[0])->getNumOutEdges(); int maxUses = candsAsHeap.getNode(mcands[0])->getNumOutEdges();
int indexWithMaxUses = 0; int indexWithMaxUses = 0;
for (unsigned i=1, N = mcands.size(); i < N; i++) { for (unsigned i=1, N = mcands.size(); i < N; i++) {
int numUses = candsAsHeap.getNode(mcands[i])->getNumOutEdges(); int numUses = candsAsHeap.getNode(mcands[i])->getNumOutEdges();

View File

@ -82,9 +82,9 @@ void BBLiveVar::calcDefUseSets() {
if (MI->getOpcode() == V9::PHI) { // for a phi node if (MI->getOpcode() == V9::PHI) { // for a phi node
const Value *ArgVal = Op; const Value *ArgVal = Op;
const BasicBlock *PredBB = cast<BasicBlock>(*++OpI); // next ptr is BB const BasicBlock *PredBB = cast<BasicBlock>(*++OpI); // next ptr is BB
PredToEdgeInSetMap[PredBB].insert(ArgVal); PredToEdgeInSetMap[PredBB].insert(ArgVal);
if (DEBUG_LV >= LV_DEBUG_Verbose) if (DEBUG_LV >= LV_DEBUG_Verbose)
std::cerr << " - phi operand " << RAV(ArgVal) << " came from BB " std::cerr << " - phi operand " << RAV(ArgVal) << " came from BB "
<< RAV(PredBB) << "\n"; << RAV(PredBB) << "\n";
@ -111,7 +111,7 @@ void BBLiveVar::calcDefUseSets() {
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// To add an operand which is a def // To add an operand which is a def
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -25,14 +25,14 @@ namespace llvm {
/// Create ModuloSchedulingPass /// Create ModuloSchedulingPass
FunctionPass *createDependenceAnalyzer() { FunctionPass *createDependenceAnalyzer() {
return new DependenceAnalyzer(); return new DependenceAnalyzer();
} }
} }
Statistic<> NoDeps("depanalyzer-nodeps", "Number of dependences eliminated"); Statistic<> NoDeps("depanalyzer-nodeps", "Number of dependences eliminated");
Statistic<> NumDeps("depanalyzer-deps", Statistic<> NumDeps("depanalyzer-deps",
"Number of dependences could not eliminate"); "Number of dependences could not eliminate");
Statistic<> AdvDeps("depanalyzer-advdeps", Statistic<> AdvDeps("depanalyzer-advdeps",
"Number of dependences using advanced techniques"); "Number of dependences using advanced techniques");
bool DependenceAnalyzer::runOnFunction(Function &F) { bool DependenceAnalyzer::runOnFunction(Function &F) {
@ -43,25 +43,25 @@ bool DependenceAnalyzer::runOnFunction(Function &F) {
return false; return false;
} }
static RegisterAnalysis<DependenceAnalyzer>X("depanalyzer", static RegisterAnalysis<DependenceAnalyzer>X("depanalyzer",
"Dependence Analyzer"); "Dependence Analyzer");
// - Get inter and intra dependences between loads and stores // - Get inter and intra dependences between loads and stores
// //
// Overview of Method: // Overview of Method:
// Step 1: Use alias analysis to determine dependencies if values are loop // Step 1: Use alias analysis to determine dependencies if values are loop
// invariant // invariant
// Step 2: If pointers are not GEP, then there is a dependence. // Step 2: If pointers are not GEP, then there is a dependence.
// Step 3: Compare GEP base pointers with AA. If no alias, no dependence. // Step 3: Compare GEP base pointers with AA. If no alias, no dependence.
// If may alias, then add a dependence. If must alias, then analyze // If may alias, then add a dependence. If must alias, then analyze
// further (Step 4) // further (Step 4)
// Step 4: do advanced analysis // Step 4: do advanced analysis
void DependenceAnalyzer::AnalyzeDeps(Value *val, Value *val2, bool valLoad, void DependenceAnalyzer::AnalyzeDeps(Value *val, Value *val2, bool valLoad,
bool val2Load, bool val2Load,
std::vector<Dependence> &deps, std::vector<Dependence> &deps,
BasicBlock *BB, BasicBlock *BB,
bool srcBeforeDest) { bool srcBeforeDest) {
bool loopInvariant = true; bool loopInvariant = true;
//Check if both are instructions and prove not loop invariant if possible //Check if both are instructions and prove not loop invariant if possible
@ -71,8 +71,8 @@ void DependenceAnalyzer::AnalyzeDeps(Value *val, Value *val2, bool valLoad,
if(Instruction *val2Inst = dyn_cast<Instruction>(val2)) if(Instruction *val2Inst = dyn_cast<Instruction>(val2))
if(val2Inst->getParent() == BB) if(val2Inst->getParent() == BB)
loopInvariant = false; loopInvariant = false;
//If Loop invariant, let AA decide //If Loop invariant, let AA decide
if(loopInvariant) { if(loopInvariant) {
if(AA->alias(val, (unsigned)TD->getTypeSize(val->getType()), if(AA->alias(val, (unsigned)TD->getTypeSize(val->getType()),
@ -84,7 +84,7 @@ void DependenceAnalyzer::AnalyzeDeps(Value *val, Value *val2, bool valLoad,
++NoDeps; ++NoDeps;
return; return;
} }
//Otherwise, continue with step 2 //Otherwise, continue with step 2
GetElementPtrInst *GP = dyn_cast<GetElementPtrInst>(val); GetElementPtrInst *GP = dyn_cast<GetElementPtrInst>(val);
@ -120,7 +120,7 @@ void DependenceAnalyzer::AnalyzeDeps(Value *val, Value *val2, bool valLoad,
// advancedDepAnalysis - Do advanced data dependence tests // advancedDepAnalysis - Do advanced data dependence tests
void DependenceAnalyzer::advancedDepAnalysis(GetElementPtrInst *gp1, void DependenceAnalyzer::advancedDepAnalysis(GetElementPtrInst *gp1,
GetElementPtrInst *gp2, GetElementPtrInst *gp2,
bool valLoad, bool valLoad,
bool val2Load, bool val2Load,
@ -139,7 +139,7 @@ void DependenceAnalyzer::advancedDepAnalysis(GetElementPtrInst *gp1,
if(Constant *c2 = dyn_cast<Constant>(gp2->getOperand(1))) if(Constant *c2 = dyn_cast<Constant>(gp2->getOperand(1)))
if(c1->isNullValue() && c2->isNullValue()) if(c1->isNullValue() && c2->isNullValue())
GPok = true; GPok = true;
if(!GPok) { if(!GPok) {
createDep(deps, valLoad, val2Load, srcBeforeDest); createDep(deps, valLoad, val2Load, srcBeforeDest);
return; return;
@ -153,7 +153,7 @@ void DependenceAnalyzer::advancedDepAnalysis(GetElementPtrInst *gp1,
Gep1Idx = c1->getOperand(0); Gep1Idx = c1->getOperand(0);
if(CastInst *c2 = dyn_cast<CastInst>(Gep2Idx)) if(CastInst *c2 = dyn_cast<CastInst>(Gep2Idx))
Gep2Idx = c2->getOperand(0); Gep2Idx = c2->getOperand(0);
//Get SCEV for each index into the area //Get SCEV for each index into the area
SCEVHandle SV1 = SE->getSCEV(Gep1Idx); SCEVHandle SV1 = SE->getSCEV(Gep1Idx);
SCEVHandle SV2 = SE->getSCEV(Gep2Idx); SCEVHandle SV2 = SE->getSCEV(Gep2Idx);
@ -188,7 +188,7 @@ void DependenceAnalyzer::advancedDepAnalysis(GetElementPtrInst *gp1,
createDep(deps, valLoad, val2Load, srcBeforeDest); createDep(deps, valLoad, val2Load, srcBeforeDest);
return; return;
} }
if(B1->getValue()->getRawValue() != 1 || B2->getValue()->getRawValue() != 1) { if(B1->getValue()->getRawValue() != 1 || B2->getValue()->getRawValue() != 1) {
createDep(deps, valLoad, val2Load, srcBeforeDest); createDep(deps, valLoad, val2Load, srcBeforeDest);
return; return;
@ -214,7 +214,7 @@ void DependenceAnalyzer::advancedDepAnalysis(GetElementPtrInst *gp1,
++NoDeps; ++NoDeps;
return; return;
} }
//Find constant index difference //Find constant index difference
int diff = A1->getValue()->getRawValue() - A2->getValue()->getRawValue(); int diff = A1->getValue()->getRawValue() - A2->getValue()->getRawValue();
//std::cerr << diff << "\n"; //std::cerr << diff << "\n";
@ -223,14 +223,14 @@ void DependenceAnalyzer::advancedDepAnalysis(GetElementPtrInst *gp1,
if(diff > 0) if(diff > 0)
createDep(deps, valLoad, val2Load, srcBeforeDest, diff); createDep(deps, valLoad, val2Load, srcBeforeDest, diff);
//assert(diff > 0 && "Expected diff to be greater then 0"); //assert(diff > 0 && "Expected diff to be greater then 0");
} }
// Create dependences once its determined these two instructions // Create dependences once its determined these two instructions
// references the same memory // references the same memory
void DependenceAnalyzer::createDep(std::vector<Dependence> &deps, void DependenceAnalyzer::createDep(std::vector<Dependence> &deps,
bool valLoad, bool val2Load, bool valLoad, bool val2Load,
bool srcBeforeDest, int diff) { bool srcBeforeDest, int diff) {
//If the source instruction occurs after the destination instruction //If the source instruction occurs after the destination instruction
@ -240,7 +240,7 @@ void DependenceAnalyzer::createDep(std::vector<Dependence> &deps,
//If load/store pair //If load/store pair
if(valLoad && !val2Load) { if(valLoad && !val2Load) {
if(srcBeforeDest) if(srcBeforeDest)
//Anti Dep //Anti Dep
deps.push_back(Dependence(diff, Dependence::AntiDep)); deps.push_back(Dependence(diff, Dependence::AntiDep));
else else
@ -250,7 +250,7 @@ void DependenceAnalyzer::createDep(std::vector<Dependence> &deps,
} }
//If store/load pair //If store/load pair
else if(!valLoad && val2Load) { else if(!valLoad && val2Load) {
if(srcBeforeDest) if(srcBeforeDest)
//True Dep //True Dep
deps.push_back(Dependence(diff, Dependence::TrueDep)); deps.push_back(Dependence(diff, Dependence::TrueDep));
else else
@ -266,10 +266,10 @@ void DependenceAnalyzer::createDep(std::vector<Dependence> &deps,
} }
//Get Dependence Info for a pair of Instructions //Get Dependence Info for a pair of Instructions
DependenceResult DependenceAnalyzer::getDependenceInfo(Instruction *inst1, DependenceResult DependenceAnalyzer::getDependenceInfo(Instruction *inst1,
Instruction *inst2, Instruction *inst2,
bool srcBeforeDest) { bool srcBeforeDest) {
std::vector<Dependence> deps; std::vector<Dependence> deps;
@ -281,24 +281,24 @@ DependenceResult DependenceAnalyzer::getDependenceInfo(Instruction *inst1,
return DependenceResult(deps); return DependenceResult(deps);
if(LoadInst *ldInst = dyn_cast<LoadInst>(inst1)) { if(LoadInst *ldInst = dyn_cast<LoadInst>(inst1)) {
if(StoreInst *stInst = dyn_cast<StoreInst>(inst2)) if(StoreInst *stInst = dyn_cast<StoreInst>(inst2))
AnalyzeDeps(ldInst->getOperand(0), stInst->getOperand(1), AnalyzeDeps(ldInst->getOperand(0), stInst->getOperand(1),
true, false, deps, ldInst->getParent(), srcBeforeDest); true, false, deps, ldInst->getParent(), srcBeforeDest);
} }
else if(StoreInst *stInst = dyn_cast<StoreInst>(inst1)) { else if(StoreInst *stInst = dyn_cast<StoreInst>(inst1)) {
if(LoadInst *ldInst = dyn_cast<LoadInst>(inst2)) if(LoadInst *ldInst = dyn_cast<LoadInst>(inst2))
AnalyzeDeps(stInst->getOperand(1), ldInst->getOperand(0), false, true, AnalyzeDeps(stInst->getOperand(1), ldInst->getOperand(0), false, true,
deps, ldInst->getParent(), srcBeforeDest); deps, ldInst->getParent(), srcBeforeDest);
else if(StoreInst *stInst2 = dyn_cast<StoreInst>(inst2)) else if(StoreInst *stInst2 = dyn_cast<StoreInst>(inst2))
AnalyzeDeps(stInst->getOperand(1), stInst2->getOperand(1), false, false, AnalyzeDeps(stInst->getOperand(1), stInst2->getOperand(1), false, false,
deps, stInst->getParent(), srcBeforeDest); deps, stInst->getParent(), srcBeforeDest);
} }
else else
assert(0 && "Expected a load or a store\n"); assert(0 && "Expected a load or a store\n");
DependenceResult dr = DependenceResult(deps); DependenceResult dr = DependenceResult(deps);
return dr; return dr;
} }

View File

@ -21,7 +21,7 @@
using namespace llvm; using namespace llvm;
//Check if all resources are free //Check if all resources are free
bool resourcesFree(MSchedGraphNode*, int, bool resourcesFree(MSchedGraphNode*, int,
std::map<int, std::map<int, int> > &resourceNumPerCycle); std::map<int, std::map<int, int> > &resourceNumPerCycle);
//Returns a boolean indicating if the start cycle needs to be increased/decreased //Returns a boolean indicating if the start cycle needs to be increased/decreased
@ -84,12 +84,12 @@ bool MSSchedule::resourceAvailable(int resourceNum, int cycle) {
isFree = false; isFree = false;
} }
} }
return isFree; return isFree;
} }
void MSSchedule::useResource(int resourceNum, int cycle) { void MSSchedule::useResource(int resourceNum, int cycle) {
//Get Map for this cycle //Get Map for this cycle
if(resourceNumPerCycle.count(cycle)) { if(resourceNumPerCycle.count(cycle)) {
if(resourceNumPerCycle[cycle].count(resourceNum)) { if(resourceNumPerCycle[cycle].count(resourceNum)) {
@ -105,7 +105,7 @@ void MSSchedule::useResource(int resourceNum, int cycle) {
resourceUse[resourceNum] = 1; resourceUse[resourceNum] = 1;
resourceNumPerCycle[cycle] = resourceUse; resourceNumPerCycle[cycle] = resourceUse;
} }
} }
bool MSSchedule::resourcesFree(MSchedGraphNode *node, int cycle, int II) { bool MSSchedule::resourcesFree(MSchedGraphNode *node, int cycle, int II) {
@ -129,34 +129,34 @@ bool MSSchedule::resourcesFree(MSchedGraphNode *node, int cycle, int II) {
//Now check all cycles for conflicts //Now check all cycles for conflicts
for(int index = 0; index < (int) cyclesMayConflict.size(); ++index) { for(int index = 0; index < (int) cyclesMayConflict.size(); ++index) {
currentCycle = cyclesMayConflict[index]; currentCycle = cyclesMayConflict[index];
//Get resource usage for this instruction //Get resource usage for this instruction
InstrRUsage rUsage = msi->getInstrRUsage(node->getInst()->getOpcode()); InstrRUsage rUsage = msi->getInstrRUsage(node->getInst()->getOpcode());
std::vector<std::vector<resourceId_t> > resources = rUsage.resourcesByCycle; std::vector<std::vector<resourceId_t> > resources = rUsage.resourcesByCycle;
//Loop over resources in each cycle and increments their usage count //Loop over resources in each cycle and increments their usage count
for(unsigned i=0; i < resources.size(); ++i) { for(unsigned i=0; i < resources.size(); ++i) {
for(unsigned j=0; j < resources[i].size(); ++j) { for(unsigned j=0; j < resources[i].size(); ++j) {
//Get Resource to check its availability //Get Resource to check its availability
int resourceNum = resources[i][j]; int resourceNum = resources[i][j];
DEBUG(std::cerr << "Attempting to schedule Resource Num: " << resourceNum << " in cycle: " << currentCycle << "\n"); DEBUG(std::cerr << "Attempting to schedule Resource Num: " << resourceNum << " in cycle: " << currentCycle << "\n");
success = resourceAvailable(resourceNum, currentCycle); success = resourceAvailable(resourceNum, currentCycle);
if(!success) if(!success)
break; break;
} }
if(!success) if(!success)
break; break;
//Increase cycle //Increase cycle
currentCycle++; currentCycle++;
} }
if(!success) if(!success)
return false; return false;
} }
@ -168,7 +168,7 @@ bool MSSchedule::resourcesFree(MSchedGraphNode *node, int cycle, int II) {
//Get resource usage for this instruction //Get resource usage for this instruction
InstrRUsage rUsage = msi->getInstrRUsage(node->getInst()->getOpcode()); InstrRUsage rUsage = msi->getInstrRUsage(node->getInst()->getOpcode());
std::vector<std::vector<resourceId_t> > resources = rUsage.resourcesByCycle; std::vector<std::vector<resourceId_t> > resources = rUsage.resourcesByCycle;
//Loop over resources in each cycle and increments their usage count //Loop over resources in each cycle and increments their usage count
for(unsigned i=0; i < resources.size(); ++i) { for(unsigned i=0; i < resources.size(); ++i) {
for(unsigned j=0; j < resources[i].size(); ++j) { for(unsigned j=0; j < resources[i].size(); ++j) {
@ -195,7 +195,7 @@ bool MSSchedule::constructKernel(int II, std::vector<MSchedGraphNode*> &branches
//Using the schedule, fold up into kernel and check resource conflicts as we go //Using the schedule, fold up into kernel and check resource conflicts as we go
std::vector<std::pair<MSchedGraphNode*, int> > tempKernel; std::vector<std::pair<MSchedGraphNode*, int> > tempKernel;
int stageNum = ((schedule.rbegin()->first-offset)+1)/ II; int stageNum = ((schedule.rbegin()->first-offset)+1)/ II;
int maxSN = 0; int maxSN = 0;
@ -212,7 +212,7 @@ bool MSSchedule::constructKernel(int II, std::vector<MSchedGraphNode*> &branches
tempKernel.push_back(std::make_pair(*I, count)); tempKernel.push_back(std::make_pair(*I, count));
maxSN = std::max(maxSN, count); maxSN = std::max(maxSN, count);
} }
} }
++count; ++count;
@ -286,7 +286,7 @@ bool MSSchedule::defPreviousStage(Value *def, int stage) {
} }
} }
} }
assert(0 && "We should always have found the def in our kernel\n"); assert(0 && "We should always have found the def in our kernel\n");
} }

View File

@ -21,7 +21,7 @@
using namespace llvm; using namespace llvm;
//Check if all resources are free //Check if all resources are free
bool resourcesFree(MSchedGraphSBNode*, int, bool resourcesFree(MSchedGraphSBNode*, int,
std::map<int, std::map<int, int> > &resourceNumPerCycle); std::map<int, std::map<int, int> > &resourceNumPerCycle);
//Returns a boolean indicating if the start cycle needs to be increased/decreased //Returns a boolean indicating if the start cycle needs to be increased/decreased
@ -84,12 +84,12 @@ bool MSScheduleSB::resourceAvailable(int resourceNum, int cycle) {
isFree = false; isFree = false;
} }
} }
return isFree; return isFree;
} }
void MSScheduleSB::useResource(int resourceNum, int cycle) { void MSScheduleSB::useResource(int resourceNum, int cycle) {
//Get Map for this cycle //Get Map for this cycle
if(resourceNumPerCycle.count(cycle)) { if(resourceNumPerCycle.count(cycle)) {
if(resourceNumPerCycle[cycle].count(resourceNum)) { if(resourceNumPerCycle[cycle].count(resourceNum)) {
@ -105,7 +105,7 @@ void MSScheduleSB::useResource(int resourceNum, int cycle) {
resourceUse[resourceNum] = 1; resourceUse[resourceNum] = 1;
resourceNumPerCycle[cycle] = resourceUse; resourceNumPerCycle[cycle] = resourceUse;
} }
} }
bool MSScheduleSB::resourcesFree(MSchedGraphSBNode *node, int cycle, int II) { bool MSScheduleSB::resourcesFree(MSchedGraphSBNode *node, int cycle, int II) {
@ -129,34 +129,34 @@ bool MSScheduleSB::resourcesFree(MSchedGraphSBNode *node, int cycle, int II) {
//Now check all cycles for conflicts //Now check all cycles for conflicts
for(int index = 0; index < (int) cyclesMayConflict.size(); ++index) { for(int index = 0; index < (int) cyclesMayConflict.size(); ++index) {
currentCycle = cyclesMayConflict[index]; currentCycle = cyclesMayConflict[index];
//Get resource usage for this instruction //Get resource usage for this instruction
InstrRUsage rUsage = msi->getInstrRUsage(node->getInst()->getOpcode()); InstrRUsage rUsage = msi->getInstrRUsage(node->getInst()->getOpcode());
std::vector<std::vector<resourceId_t> > resources = rUsage.resourcesByCycle; std::vector<std::vector<resourceId_t> > resources = rUsage.resourcesByCycle;
//Loop over resources in each cycle and increments their usage count //Loop over resources in each cycle and increments their usage count
for(unsigned i=0; i < resources.size(); ++i) { for(unsigned i=0; i < resources.size(); ++i) {
for(unsigned j=0; j < resources[i].size(); ++j) { for(unsigned j=0; j < resources[i].size(); ++j) {
//Get Resource to check its availability //Get Resource to check its availability
int resourceNum = resources[i][j]; int resourceNum = resources[i][j];
DEBUG(std::cerr << "Attempting to schedule Resource Num: " << resourceNum << " in cycle: " << currentCycle << "\n"); DEBUG(std::cerr << "Attempting to schedule Resource Num: " << resourceNum << " in cycle: " << currentCycle << "\n");
success = resourceAvailable(resourceNum, currentCycle); success = resourceAvailable(resourceNum, currentCycle);
if(!success) if(!success)
break; break;
} }
if(!success) if(!success)
break; break;
//Increase cycle //Increase cycle
currentCycle++; currentCycle++;
} }
if(!success) if(!success)
return false; return false;
} }
@ -168,7 +168,7 @@ bool MSScheduleSB::resourcesFree(MSchedGraphSBNode *node, int cycle, int II) {
//Get resource usage for this instruction //Get resource usage for this instruction
InstrRUsage rUsage = msi->getInstrRUsage(node->getInst()->getOpcode()); InstrRUsage rUsage = msi->getInstrRUsage(node->getInst()->getOpcode());
std::vector<std::vector<resourceId_t> > resources = rUsage.resourcesByCycle; std::vector<std::vector<resourceId_t> > resources = rUsage.resourcesByCycle;
//Loop over resources in each cycle and increments their usage count //Loop over resources in each cycle and increments their usage count
for(unsigned i=0; i < resources.size(); ++i) { for(unsigned i=0; i < resources.size(); ++i) {
for(unsigned j=0; j < resources[i].size(); ++j) { for(unsigned j=0; j < resources[i].size(); ++j) {
@ -195,7 +195,7 @@ bool MSScheduleSB::constructKernel(int II, std::vector<MSchedGraphSBNode*> &bran
//Using the schedule, fold up into kernel and check resource conflicts as we go //Using the schedule, fold up into kernel and check resource conflicts as we go
std::vector<std::pair<MSchedGraphSBNode*, int> > tempKernel; std::vector<std::pair<MSchedGraphSBNode*, int> > tempKernel;
int stageNum = ((schedule.rbegin()->first-offset)+1)/ II; int stageNum = ((schedule.rbegin()->first-offset)+1)/ II;
int maxSN = 0; int maxSN = 0;
@ -212,7 +212,7 @@ bool MSScheduleSB::constructKernel(int II, std::vector<MSchedGraphSBNode*> &bran
tempKernel.push_back(std::make_pair(*I, count)); tempKernel.push_back(std::make_pair(*I, count));
maxSN = std::max(maxSN, count); maxSN = std::max(maxSN, count);
} }
} }
++count; ++count;
@ -293,7 +293,7 @@ bool MSScheduleSB::defPreviousStage(Value *def, int stage) {
} }
} }
} }
assert(0 && "We should always have found the def in our kernel\n"); assert(0 && "We should always have found the def in our kernel\n");
} }

View File

@ -34,8 +34,8 @@ using namespace llvm;
//MSchedGraphNode constructor //MSchedGraphNode constructor
MSchedGraphNode::MSchedGraphNode(const MachineInstr* inst, MSchedGraphNode::MSchedGraphNode(const MachineInstr* inst,
MSchedGraph *graph, unsigned idx, MSchedGraph *graph, unsigned idx,
unsigned late, bool isBranch) unsigned late, bool isBranch)
: Inst(inst), Parent(graph), index(idx), latency(late), : Inst(inst), Parent(graph), index(idx), latency(late),
isBranchInstr(isBranch) { isBranchInstr(isBranch) {
//Add to the graph //Add to the graph
@ -75,7 +75,7 @@ MSchedGraphEdge MSchedGraphNode::getInEdge(MSchedGraphNode *pred) {
//Get the iteration difference for the edge from this node to its successor //Get the iteration difference for the edge from this node to its successor
unsigned MSchedGraphNode::getIteDiff(MSchedGraphNode *succ) { unsigned MSchedGraphNode::getIteDiff(MSchedGraphNode *succ) {
for(std::vector<MSchedGraphEdge>::iterator I = Successors.begin(), for(std::vector<MSchedGraphEdge>::iterator I = Successors.begin(),
E = Successors.end(); E = Successors.end();
I != E; ++I) { I != E; ++I) {
if(I->getDest() == succ) if(I->getDest() == succ)
@ -89,7 +89,7 @@ unsigned MSchedGraphNode::getInEdgeNum(MSchedGraphNode *pred) {
//Loop over all the successors of our predecessor //Loop over all the successors of our predecessor
//return the edge the corresponds to this in edge //return the edge the corresponds to this in edge
int count = 0; int count = 0;
for(MSchedGraphNode::succ_iterator I = pred->succ_begin(), for(MSchedGraphNode::succ_iterator I = pred->succ_begin(),
E = pred->succ_end(); E = pred->succ_end();
I != E; ++I) { I != E; ++I) {
if(*I == this) if(*I == this)
@ -110,7 +110,7 @@ bool MSchedGraphNode::isSuccessor(MSchedGraphNode *succ) {
//Dtermine if pred is a predecessor of this node //Dtermine if pred is a predecessor of this node
bool MSchedGraphNode::isPredecessor(MSchedGraphNode *pred) { bool MSchedGraphNode::isPredecessor(MSchedGraphNode *pred) {
if(std::find( Predecessors.begin(), Predecessors.end(), if(std::find( Predecessors.begin(), Predecessors.end(),
pred) != Predecessors.end()) pred) != Predecessors.end())
return true; return true;
else else
@ -148,10 +148,10 @@ void MSchedGraph::deleteNode(MSchedGraphNode *node) {
//we ignore instructions associated to the index variable since this //we ignore instructions associated to the index variable since this
//is a special case in Modulo Scheduling. We only want to deal with //is a special case in Modulo Scheduling. We only want to deal with
//the body of the loop. //the body of the loop.
MSchedGraph::MSchedGraph(const MachineBasicBlock *bb, MSchedGraph::MSchedGraph(const MachineBasicBlock *bb,
const TargetMachine &targ, const TargetMachine &targ,
std::map<const MachineInstr*, unsigned> &ignoreInstrs, std::map<const MachineInstr*, unsigned> &ignoreInstrs,
DependenceAnalyzer &DA, DependenceAnalyzer &DA,
std::map<MachineInstr*, Instruction*> &machineTollvm) std::map<MachineInstr*, Instruction*> &machineTollvm)
: Target(targ) { : Target(targ) {
@ -159,7 +159,7 @@ MSchedGraph::MSchedGraph(const MachineBasicBlock *bb,
assert(bb != NULL && "Basic Block is null"); assert(bb != NULL && "Basic Block is null");
BBs.push_back(bb); BBs.push_back(bb);
//Create nodes and edges for this BB //Create nodes and edges for this BB
buildNodesAndEdges(ignoreInstrs, DA, machineTollvm); buildNodesAndEdges(ignoreInstrs, DA, machineTollvm);
@ -171,16 +171,16 @@ MSchedGraph::MSchedGraph(const MachineBasicBlock *bb,
//we ignore instructions associated to the index variable since this //we ignore instructions associated to the index variable since this
//is a special case in Modulo Scheduling. We only want to deal with //is a special case in Modulo Scheduling. We only want to deal with
//the body of the loop. //the body of the loop.
MSchedGraph::MSchedGraph(std::vector<const MachineBasicBlock*> &bbs, MSchedGraph::MSchedGraph(std::vector<const MachineBasicBlock*> &bbs,
const TargetMachine &targ, const TargetMachine &targ,
std::map<const MachineInstr*, unsigned> &ignoreInstrs, std::map<const MachineInstr*, unsigned> &ignoreInstrs,
DependenceAnalyzer &DA, DependenceAnalyzer &DA,
std::map<MachineInstr*, Instruction*> &machineTollvm) std::map<MachineInstr*, Instruction*> &machineTollvm)
: BBs(bbs), Target(targ) { : BBs(bbs), Target(targ) {
//Make sure there is at least one BB and it is not null, //Make sure there is at least one BB and it is not null,
assert(((bbs.size() >= 1) && bbs[1] != NULL) && "Basic Block is null"); assert(((bbs.size() >= 1) && bbs[1] != NULL) && "Basic Block is null");
//Create nodes and edges for this BB //Create nodes and edges for this BB
buildNodesAndEdges(ignoreInstrs, DA, machineTollvm); buildNodesAndEdges(ignoreInstrs, DA, machineTollvm);
@ -190,15 +190,15 @@ MSchedGraph::MSchedGraph(std::vector<const MachineBasicBlock*> &bbs,
//Copies the graph and keeps a map from old to new nodes //Copies the graph and keeps a map from old to new nodes
MSchedGraph::MSchedGraph(const MSchedGraph &G, MSchedGraph::MSchedGraph(const MSchedGraph &G,
std::map<MSchedGraphNode*, MSchedGraphNode*> &newNodes) std::map<MSchedGraphNode*, MSchedGraphNode*> &newNodes)
: Target(G.Target) { : Target(G.Target) {
BBs = G.BBs; BBs = G.BBs;
std::map<MSchedGraphNode*, MSchedGraphNode*> oldToNew; std::map<MSchedGraphNode*, MSchedGraphNode*> oldToNew;
//Copy all nodes //Copy all nodes
for(MSchedGraph::const_iterator N = G.GraphMap.begin(), for(MSchedGraph::const_iterator N = G.GraphMap.begin(),
NE = G.GraphMap.end(); N != NE; ++N) { NE = G.GraphMap.end(); N != NE; ++N) {
MSchedGraphNode *newNode = new MSchedGraphNode(*(N->second)); MSchedGraphNode *newNode = new MSchedGraphNode(*(N->second));
@ -208,7 +208,7 @@ MSchedGraph::MSchedGraph(const MSchedGraph &G,
} }
//Loop over nodes and update edges to point to new nodes //Loop over nodes and update edges to point to new nodes
for(MSchedGraph::iterator N = GraphMap.begin(), NE = GraphMap.end(); for(MSchedGraph::iterator N = GraphMap.begin(), NE = GraphMap.end();
N != NE; ++N) { N != NE; ++N) {
//Get the node we are dealing with //Get the node we are dealing with
@ -231,16 +231,16 @@ MSchedGraph::MSchedGraph(const MSchedGraph &G,
//Deconstructor, deletes all nodes in the graph //Deconstructor, deletes all nodes in the graph
MSchedGraph::~MSchedGraph () { MSchedGraph::~MSchedGraph () {
for(MSchedGraph::iterator I = GraphMap.begin(), E = GraphMap.end(); for(MSchedGraph::iterator I = GraphMap.begin(), E = GraphMap.end();
I != E; ++I) I != E; ++I)
delete I->second; delete I->second;
} }
//Print out graph //Print out graph
void MSchedGraph::print(std::ostream &os) const { void MSchedGraph::print(std::ostream &os) const {
for(MSchedGraph::const_iterator N = GraphMap.begin(), NE = GraphMap.end(); for(MSchedGraph::const_iterator N = GraphMap.begin(), NE = GraphMap.end();
N != NE; ++N) { N != NE; ++N) {
//Get the node we are dealing with //Get the node we are dealing with
MSchedGraphNode *node = &*(N->second); MSchedGraphNode *node = &*(N->second);
@ -261,9 +261,9 @@ void MSchedGraph::print(std::ostream &os) const {
int MSchedGraph::totalDelay() { int MSchedGraph::totalDelay() {
int sum = 0; int sum = 0;
for(MSchedGraph::const_iterator N = GraphMap.begin(), NE = GraphMap.end(); for(MSchedGraph::const_iterator N = GraphMap.begin(), NE = GraphMap.end();
N != NE; ++N) { N != NE; ++N) {
//Get the node we are dealing with //Get the node we are dealing with
MSchedGraphNode *node = &*(N->second); MSchedGraphNode *node = &*(N->second);
sum += node->getLatency(); sum += node->getLatency();
@ -271,7 +271,7 @@ int MSchedGraph::totalDelay() {
return sum; return sum;
} }
//Experimental code to add edges from the branch to all nodes dependent upon it. //Experimental code to add edges from the branch to all nodes dependent upon it.
void hasPath(MSchedGraphNode *node, std::set<MSchedGraphNode*> &visited, void hasPath(MSchedGraphNode *node, std::set<MSchedGraphNode*> &visited,
std::set<MSchedGraphNode*> &branches, MSchedGraphNode *startNode, std::set<MSchedGraphNode*> &branches, MSchedGraphNode *startNode,
std::set<std::pair<MSchedGraphNode*,MSchedGraphNode*> > &newEdges ) { std::set<std::pair<MSchedGraphNode*,MSchedGraphNode*> > &newEdges ) {
@ -298,7 +298,7 @@ void MSchedGraph::addBranchEdges() {
std::set<MSchedGraphNode*> branches; std::set<MSchedGraphNode*> branches;
std::set<MSchedGraphNode*> nodes; std::set<MSchedGraphNode*> nodes;
for(MSchedGraph::iterator I = GraphMap.begin(), E = GraphMap.end(); for(MSchedGraph::iterator I = GraphMap.begin(), E = GraphMap.end();
I != E; ++I) { I != E; ++I) {
if(I->second->isBranch()) if(I->second->isBranch())
if(I->second->hasPredecessors()) if(I->second->hasPredecessors())
@ -308,7 +308,7 @@ void MSchedGraph::addBranchEdges() {
//See if there is a path first instruction to the branches, if so, add an //See if there is a path first instruction to the branches, if so, add an
//iteration dependence between that node and the branch //iteration dependence between that node and the branch
std::set<std::pair<MSchedGraphNode*, MSchedGraphNode*> > newEdges; std::set<std::pair<MSchedGraphNode*, MSchedGraphNode*> > newEdges;
for(MSchedGraph::iterator I = GraphMap.begin(), E = GraphMap.end(); for(MSchedGraph::iterator I = GraphMap.begin(), E = GraphMap.end();
I != E; ++I) { I != E; ++I) {
std::set<MSchedGraphNode*> visited; std::set<MSchedGraphNode*> visited;
hasPath((I->second), visited, branches, (I->second), newEdges); hasPath((I->second), visited, branches, (I->second), newEdges);
@ -347,7 +347,7 @@ void MSchedGraph::addBranchEdges() {
void MSchedGraph::buildNodesAndEdges(std::map<const MachineInstr*, unsigned> &ignoreInstrs, void MSchedGraph::buildNodesAndEdges(std::map<const MachineInstr*, unsigned> &ignoreInstrs,
DependenceAnalyzer &DA, DependenceAnalyzer &DA,
std::map<MachineInstr*, Instruction*> &machineTollvm) { std::map<MachineInstr*, Instruction*> &machineTollvm) {
//Get Machine target information for calculating latency //Get Machine target information for calculating latency
const TargetInstrInfo *MTI = Target.getInstrInfo(); const TargetInstrInfo *MTI = Target.getInstrInfo();
@ -360,28 +360,28 @@ void MSchedGraph::buildNodesAndEdges(std::map<const MachineInstr*, unsigned> &ig
std::vector<const MachineInstr*> phiInstrs; std::vector<const MachineInstr*> phiInstrs;
unsigned index = 0; unsigned index = 0;
for(std::vector<const MachineBasicBlock*>::iterator B = BBs.begin(), for(std::vector<const MachineBasicBlock*>::iterator B = BBs.begin(),
BE = BBs.end(); B != BE; ++B) { BE = BBs.end(); B != BE; ++B) {
const MachineBasicBlock *BB = *B; const MachineBasicBlock *BB = *B;
//Loop over instructions in MBB and add nodes and edges //Loop over instructions in MBB and add nodes and edges
for (MachineBasicBlock::const_iterator MI = BB->begin(), e = BB->end(); for (MachineBasicBlock::const_iterator MI = BB->begin(), e = BB->end();
MI != e; ++MI) { MI != e; ++MI) {
//Ignore indvar instructions //Ignore indvar instructions
if(ignoreInstrs.count(MI)) { if(ignoreInstrs.count(MI)) {
++index; ++index;
continue; continue;
} }
//Get each instruction of machine basic block, get the delay //Get each instruction of machine basic block, get the delay
//using the op code, create a new node for it, and add to the //using the op code, create a new node for it, and add to the
//graph. //graph.
MachineOpCode opCode = MI->getOpcode(); MachineOpCode opCode = MI->getOpcode();
int delay; int delay;
#if 0 // FIXME: LOOK INTO THIS #if 0 // FIXME: LOOK INTO THIS
//Check if subsequent instructions can be issued before //Check if subsequent instructions can be issued before
//the result is ready, if so use min delay. //the result is ready, if so use min delay.
@ -391,78 +391,78 @@ void MSchedGraph::buildNodesAndEdges(std::map<const MachineInstr*, unsigned> &ig
#endif #endif
//Get delay //Get delay
delay = MTI->maxLatency(opCode); delay = MTI->maxLatency(opCode);
//Create new node for this machine instruction and add to the graph. //Create new node for this machine instruction and add to the graph.
//Create only if not a nop //Create only if not a nop
if(MTI->isNop(opCode)) if(MTI->isNop(opCode))
continue; continue;
//Sparc BE does not use PHI opcode, so assert on this case //Sparc BE does not use PHI opcode, so assert on this case
assert(opCode != TargetInstrInfo::PHI && "Did not expect PHI opcode"); assert(opCode != TargetInstrInfo::PHI && "Did not expect PHI opcode");
bool isBranch = false; bool isBranch = false;
//We want to flag the branch node to treat it special //We want to flag the branch node to treat it special
if(MTI->isBranch(opCode)) if(MTI->isBranch(opCode))
isBranch = true; isBranch = true;
//Node is created and added to the graph automatically //Node is created and added to the graph automatically
MSchedGraphNode *node = new MSchedGraphNode(MI, this, index, delay, MSchedGraphNode *node = new MSchedGraphNode(MI, this, index, delay,
isBranch); isBranch);
DEBUG(std::cerr << "Created Node: " << *node << "\n"); DEBUG(std::cerr << "Created Node: " << *node << "\n");
//Check OpCode to keep track of memory operations to add memory //Check OpCode to keep track of memory operations to add memory
//dependencies later. //dependencies later.
if(MTI->isLoad(opCode) || MTI->isStore(opCode)) if(MTI->isLoad(opCode) || MTI->isStore(opCode))
memInstructions.push_back(node); memInstructions.push_back(node);
//Loop over all operands, and put them into the register number to //Loop over all operands, and put them into the register number to
//graph node map for determining dependencies //graph node map for determining dependencies
//If an operands is a use/def, we have an anti dependence to itself //If an operands is a use/def, we have an anti dependence to itself
for(unsigned i=0; i < MI->getNumOperands(); ++i) { for(unsigned i=0; i < MI->getNumOperands(); ++i) {
//Get Operand //Get Operand
const MachineOperand &mOp = MI->getOperand(i); const MachineOperand &mOp = MI->getOperand(i);
//Check if it has an allocated register //Check if it has an allocated register
if(mOp.hasAllocatedReg()) { if(mOp.hasAllocatedReg()) {
int regNum = mOp.getReg(); int regNum = mOp.getReg();
if(regNum != SparcV9::g0) { if(regNum != SparcV9::g0) {
//Put into our map //Put into our map
regNumtoNodeMap[regNum].push_back(std::make_pair(i, node)); regNumtoNodeMap[regNum].push_back(std::make_pair(i, node));
} }
continue; continue;
} }
//Add virtual registers dependencies //Add virtual registers dependencies
//Check if any exist in the value map already and create dependencies //Check if any exist in the value map already and create dependencies
//between them. //between them.
if(mOp.getType() == MachineOperand::MO_VirtualRegister if(mOp.getType() == MachineOperand::MO_VirtualRegister
|| mOp.getType() == MachineOperand::MO_CCRegister) { || mOp.getType() == MachineOperand::MO_CCRegister) {
//Make sure virtual register value is not null //Make sure virtual register value is not null
assert((mOp.getVRegValue() != NULL) && "Null value is defined"); assert((mOp.getVRegValue() != NULL) && "Null value is defined");
//Check if this is a read operation in a phi node, if so DO NOT PROCESS //Check if this is a read operation in a phi node, if so DO NOT PROCESS
if(mOp.isUse() && (opCode == TargetInstrInfo::PHI)) { if(mOp.isUse() && (opCode == TargetInstrInfo::PHI)) {
DEBUG(std::cerr << "Read Operation in a PHI node\n"); DEBUG(std::cerr << "Read Operation in a PHI node\n");
continue; continue;
} }
if (const Value* srcI = mOp.getVRegValue()) { if (const Value* srcI = mOp.getVRegValue()) {
//Find value in the map //Find value in the map
std::map<const Value*, std::vector<OpIndexNodePair> >::iterator V std::map<const Value*, std::vector<OpIndexNodePair> >::iterator V
= valuetoNodeMap.find(srcI); = valuetoNodeMap.find(srcI);
//If there is something in the map already, add edges from //If there is something in the map already, add edges from
//those instructions //those instructions
//to this one we are processing //to this one we are processing
if(V != valuetoNodeMap.end()) { if(V != valuetoNodeMap.end()) {
addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(), phiInstrs); addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(), phiInstrs);
//Add to value map //Add to value map
V->second.push_back(std::make_pair(i,node)); V->second.push_back(std::make_pair(i,node));
} }
@ -475,11 +475,11 @@ void MSchedGraph::buildNodesAndEdges(std::map<const MachineInstr*, unsigned> &ig
} }
++index; ++index;
} }
//Loop over LLVM BB, examine phi instructions, and add them to our //Loop over LLVM BB, examine phi instructions, and add them to our
//phiInstr list to process //phiInstr list to process
const BasicBlock *llvm_bb = BB->getBasicBlock(); const BasicBlock *llvm_bb = BB->getBasicBlock();
for(BasicBlock::const_iterator I = llvm_bb->begin(), E = llvm_bb->end(); for(BasicBlock::const_iterator I = llvm_bb->begin(), E = llvm_bb->end();
I != E; ++I) { I != E; ++I) {
if(const PHINode *PN = dyn_cast<PHINode>(I)) { if(const PHINode *PN = dyn_cast<PHINode>(I)) {
MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(PN); MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(PN);
@ -490,46 +490,46 @@ void MSchedGraph::buildNodesAndEdges(std::map<const MachineInstr*, unsigned> &ig
} }
} }
} }
} }
addMemEdges(memInstructions, DA, machineTollvm); addMemEdges(memInstructions, DA, machineTollvm);
addMachRegEdges(regNumtoNodeMap); addMachRegEdges(regNumtoNodeMap);
//Finally deal with PHI Nodes and Value* //Finally deal with PHI Nodes and Value*
for(std::vector<const MachineInstr*>::iterator I = phiInstrs.begin(), for(std::vector<const MachineInstr*>::iterator I = phiInstrs.begin(),
E = phiInstrs.end(); I != E; ++I) { E = phiInstrs.end(); I != E; ++I) {
//Get Node for this instruction //Get Node for this instruction
std::map<const MachineInstr*, MSchedGraphNode*>::iterator X; std::map<const MachineInstr*, MSchedGraphNode*>::iterator X;
X = find(*I); X = find(*I);
if(X == GraphMap.end()) if(X == GraphMap.end())
continue; continue;
MSchedGraphNode *node = X->second; MSchedGraphNode *node = X->second;
DEBUG(std::cerr << "Adding ite diff edges for node: " << *node << "\n"); DEBUG(std::cerr << "Adding ite diff edges for node: " << *node << "\n");
//Loop over operands for this instruction and add value edges //Loop over operands for this instruction and add value edges
for(unsigned i=0; i < (*I)->getNumOperands(); ++i) { for(unsigned i=0; i < (*I)->getNumOperands(); ++i) {
//Get Operand //Get Operand
const MachineOperand &mOp = (*I)->getOperand(i); const MachineOperand &mOp = (*I)->getOperand(i);
if((mOp.getType() == MachineOperand::MO_VirtualRegister if((mOp.getType() == MachineOperand::MO_VirtualRegister
|| mOp.getType() == MachineOperand::MO_CCRegister) && mOp.isUse()) { || mOp.getType() == MachineOperand::MO_CCRegister) && mOp.isUse()) {
//find the value in the map //find the value in the map
if (const Value* srcI = mOp.getVRegValue()) { if (const Value* srcI = mOp.getVRegValue()) {
//Find value in the map //Find value in the map
std::map<const Value*, std::vector<OpIndexNodePair> >::iterator V std::map<const Value*, std::vector<OpIndexNodePair> >::iterator V
= valuetoNodeMap.find(srcI); = valuetoNodeMap.find(srcI);
//If there is something in the map already, add edges from //If there is something in the map already, add edges from
//those instructions //those instructions
//to this one we are processing //to this one we are processing
if(V != valuetoNodeMap.end()) { if(V != valuetoNodeMap.end()) {
addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(), addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(),
phiInstrs, 1); phiInstrs, 1);
} }
} }
@ -582,7 +582,7 @@ void MSchedGraph::addMachRegEdges(std::map<int, std::vector<OpIndexNodePair> >&
//Loop over all machine registers in the map, and add dependencies //Loop over all machine registers in the map, and add dependencies
//between the instructions that use it //between the instructions that use it
typedef std::map<int, std::vector<OpIndexNodePair> > regNodeMap; typedef std::map<int, std::vector<OpIndexNodePair> > regNodeMap;
for(regNodeMap::iterator I = regNumtoNodeMap.begin(); for(regNodeMap::iterator I = regNumtoNodeMap.begin();
I != regNumtoNodeMap.end(); ++I) { I != regNumtoNodeMap.end(); ++I) {
//Get the register number //Get the register number
int regNum = (*I).first; int regNum = (*I).first;
@ -609,33 +609,33 @@ void MSchedGraph::addMachRegEdges(std::map<int, std::vector<OpIndexNodePair> >&
//Look at all instructions after this in execution order //Look at all instructions after this in execution order
for(unsigned j=i+1; j < Nodes.size(); ++j) { for(unsigned j=i+1; j < Nodes.size(); ++j) {
//Sink node is a write //Sink node is a write
if(Nodes[j].second->getInst()->getOperand(Nodes[j].first).isDef()) { if(Nodes[j].second->getInst()->getOperand(Nodes[j].first).isDef()) {
//Src only uses the register (read) //Src only uses the register (read)
if(srcIsUse) if(srcIsUse)
srcNode->addOutEdge(Nodes[j].second, srcNode->addOutEdge(Nodes[j].second,
MSchedGraphEdge::MachineRegister, MSchedGraphEdge::MachineRegister,
MSchedGraphEdge::AntiDep); MSchedGraphEdge::AntiDep);
else if(srcIsUseandDef) { else if(srcIsUseandDef) {
srcNode->addOutEdge(Nodes[j].second, srcNode->addOutEdge(Nodes[j].second,
MSchedGraphEdge::MachineRegister, MSchedGraphEdge::MachineRegister,
MSchedGraphEdge::AntiDep); MSchedGraphEdge::AntiDep);
srcNode->addOutEdge(Nodes[j].second, srcNode->addOutEdge(Nodes[j].second,
MSchedGraphEdge::MachineRegister, MSchedGraphEdge::MachineRegister,
MSchedGraphEdge::OutputDep); MSchedGraphEdge::OutputDep);
} }
else else
srcNode->addOutEdge(Nodes[j].second, srcNode->addOutEdge(Nodes[j].second,
MSchedGraphEdge::MachineRegister, MSchedGraphEdge::MachineRegister,
MSchedGraphEdge::OutputDep); MSchedGraphEdge::OutputDep);
} }
//Dest node is a read //Dest node is a read
else { else {
if(!srcIsUse || srcIsUseandDef) if(!srcIsUse || srcIsUseandDef)
srcNode->addOutEdge(Nodes[j].second, srcNode->addOutEdge(Nodes[j].second,
MSchedGraphEdge::MachineRegister, MSchedGraphEdge::MachineRegister,
MSchedGraphEdge::TrueDep); MSchedGraphEdge::TrueDep);
} }
@ -649,31 +649,31 @@ void MSchedGraph::addMachRegEdges(std::map<int, std::vector<OpIndexNodePair> >&
if(Nodes[j].second->getInst()->getOperand(Nodes[j].first).isDef()) { if(Nodes[j].second->getInst()->getOperand(Nodes[j].first).isDef()) {
//Src only uses the register (read) //Src only uses the register (read)
if(srcIsUse) if(srcIsUse)
srcNode->addOutEdge(Nodes[j].second, srcNode->addOutEdge(Nodes[j].second,
MSchedGraphEdge::MachineRegister, MSchedGraphEdge::MachineRegister,
MSchedGraphEdge::AntiDep, 1); MSchedGraphEdge::AntiDep, 1);
else if(srcIsUseandDef) { else if(srcIsUseandDef) {
srcNode->addOutEdge(Nodes[j].second, srcNode->addOutEdge(Nodes[j].second,
MSchedGraphEdge::MachineRegister, MSchedGraphEdge::MachineRegister,
MSchedGraphEdge::AntiDep, 1); MSchedGraphEdge::AntiDep, 1);
srcNode->addOutEdge(Nodes[j].second, srcNode->addOutEdge(Nodes[j].second,
MSchedGraphEdge::MachineRegister, MSchedGraphEdge::MachineRegister,
MSchedGraphEdge::OutputDep, 1); MSchedGraphEdge::OutputDep, 1);
} }
else else
srcNode->addOutEdge(Nodes[j].second, srcNode->addOutEdge(Nodes[j].second,
MSchedGraphEdge::MachineRegister, MSchedGraphEdge::MachineRegister,
MSchedGraphEdge::OutputDep, 1); MSchedGraphEdge::OutputDep, 1);
} }
//Dest node is a read //Dest node is a read
else { else {
if(!srcIsUse || srcIsUseandDef) if(!srcIsUse || srcIsUseandDef)
srcNode->addOutEdge(Nodes[j].second, srcNode->addOutEdge(Nodes[j].second,
MSchedGraphEdge::MachineRegister, MSchedGraphEdge::MachineRegister,
MSchedGraphEdge::TrueDep,1 ); MSchedGraphEdge::TrueDep,1 );
} }
} }
@ -685,8 +685,8 @@ void MSchedGraph::addMachRegEdges(std::map<int, std::vector<OpIndexNodePair> >&
//Add edges between all loads and stores //Add edges between all loads and stores
//Can be less strict with alias analysis and data dependence analysis. //Can be less strict with alias analysis and data dependence analysis.
void MSchedGraph::addMemEdges(const std::vector<MSchedGraphNode*>& memInst, void MSchedGraph::addMemEdges(const std::vector<MSchedGraphNode*>& memInst,
DependenceAnalyzer &DA, DependenceAnalyzer &DA,
std::map<MachineInstr*, Instruction*> &machineTollvm) { std::map<MachineInstr*, Instruction*> &machineTollvm) {
//Get Target machine instruction info //Get Target machine instruction info
@ -700,7 +700,7 @@ void MSchedGraph::addMemEdges(const std::vector<MSchedGraphNode*>& memInst,
//Get the machine opCode to determine type of memory instruction //Get the machine opCode to determine type of memory instruction
MachineOpCode srcNodeOpCode = srcInst->getOpcode(); MachineOpCode srcNodeOpCode = srcInst->getOpcode();
//All instructions after this one in execution order have an //All instructions after this one in execution order have an
//iteration delay of 0 //iteration delay of 0
for(unsigned destIndex = 0; destIndex < memInst.size(); ++destIndex) { for(unsigned destIndex = 0; destIndex < memInst.size(); ++destIndex) {
@ -713,19 +713,19 @@ void MSchedGraph::addMemEdges(const std::vector<MSchedGraphNode*>& memInst,
DEBUG(std::cerr << "MInst1: " << *srcInst << "\n"); DEBUG(std::cerr << "MInst1: " << *srcInst << "\n");
DEBUG(std::cerr << "MInst2: " << *destInst << "\n"); DEBUG(std::cerr << "MInst2: " << *destInst << "\n");
//Assuming instructions without corresponding llvm instructions //Assuming instructions without corresponding llvm instructions
//are from constant pools. //are from constant pools.
if (!machineTollvm.count(srcInst) || !machineTollvm.count(destInst)) if (!machineTollvm.count(srcInst) || !machineTollvm.count(destInst))
continue; continue;
bool useDepAnalyzer = true; bool useDepAnalyzer = true;
//Some machine loads and stores are generated by casts, so be //Some machine loads and stores are generated by casts, so be
//conservative and always add deps //conservative and always add deps
Instruction *srcLLVM = machineTollvm[srcInst]; Instruction *srcLLVM = machineTollvm[srcInst];
Instruction *destLLVM = machineTollvm[destInst]; Instruction *destLLVM = machineTollvm[destInst];
if(!isa<LoadInst>(srcLLVM) if(!isa<LoadInst>(srcLLVM)
&& !isa<StoreInst>(srcLLVM)) { && !isa<StoreInst>(srcLLVM)) {
if(isa<BinaryOperator>(srcLLVM)) { if(isa<BinaryOperator>(srcLLVM)) {
if(isa<ConstantFP>(srcLLVM->getOperand(0)) || isa<ConstantFP>(srcLLVM->getOperand(1))) if(isa<ConstantFP>(srcLLVM->getOperand(0)) || isa<ConstantFP>(srcLLVM->getOperand(1)))
@ -733,7 +733,7 @@ void MSchedGraph::addMemEdges(const std::vector<MSchedGraphNode*>& memInst,
} }
useDepAnalyzer = false; useDepAnalyzer = false;
} }
if(!isa<LoadInst>(destLLVM) if(!isa<LoadInst>(destLLVM)
&& !isa<StoreInst>(destLLVM)) { && !isa<StoreInst>(destLLVM)) {
if(isa<BinaryOperator>(destLLVM)) { if(isa<BinaryOperator>(destLLVM)) {
if(isa<ConstantFP>(destLLVM->getOperand(0)) || isa<ConstantFP>(destLLVM->getOperand(1))) if(isa<ConstantFP>(destLLVM->getOperand(0)) || isa<ConstantFP>(destLLVM->getOperand(1)))
@ -748,29 +748,29 @@ void MSchedGraph::addMemEdges(const std::vector<MSchedGraphNode*>& memInst,
if(destIndex < srcIndex) if(destIndex < srcIndex)
srcBeforeDest = false; srcBeforeDest = false;
DependenceResult dr = DA.getDependenceInfo(machineTollvm[srcInst], DependenceResult dr = DA.getDependenceInfo(machineTollvm[srcInst],
machineTollvm[destInst], machineTollvm[destInst],
srcBeforeDest); srcBeforeDest);
for(std::vector<Dependence>::iterator d = dr.dependences.begin(), for(std::vector<Dependence>::iterator d = dr.dependences.begin(),
de = dr.dependences.end(); d != de; ++d) { de = dr.dependences.end(); d != de; ++d) {
//Add edge from load to store //Add edge from load to store
memInst[srcIndex]->addOutEdge(memInst[destIndex], memInst[srcIndex]->addOutEdge(memInst[destIndex],
MSchedGraphEdge::MemoryDep, MSchedGraphEdge::MemoryDep,
d->getDepType(), d->getIteDiff()); d->getDepType(), d->getIteDiff());
} }
} }
//Otherwise, we can not do any further analysis and must make a dependence //Otherwise, we can not do any further analysis and must make a dependence
else { else {
//Get the machine opCode to determine type of memory instruction //Get the machine opCode to determine type of memory instruction
MachineOpCode destNodeOpCode = destInst->getOpcode(); MachineOpCode destNodeOpCode = destInst->getOpcode();
//Get the Value* that we are reading from the load, always the first op //Get the Value* that we are reading from the load, always the first op
const MachineOperand &mOp = srcInst->getOperand(0); const MachineOperand &mOp = srcInst->getOperand(0);
const MachineOperand &mOp2 = destInst->getOperand(0); const MachineOperand &mOp2 = destInst->getOperand(0);
if(mOp.hasAllocatedReg()) if(mOp.hasAllocatedReg())
if(mOp.getReg() == SparcV9::g0) if(mOp.getReg() == SparcV9::g0)
continue; continue;
@ -783,19 +783,19 @@ void MSchedGraph::addMemEdges(const std::vector<MSchedGraphNode*>& memInst,
if(TMI->isLoad(srcNodeOpCode)) { if(TMI->isLoad(srcNodeOpCode)) {
if(TMI->isStore(destNodeOpCode)) if(TMI->isStore(destNodeOpCode))
memInst[srcIndex]->addOutEdge(memInst[destIndex], memInst[srcIndex]->addOutEdge(memInst[destIndex],
MSchedGraphEdge::MemoryDep, MSchedGraphEdge::MemoryDep,
MSchedGraphEdge::AntiDep, 0); MSchedGraphEdge::AntiDep, 0);
} }
else if(TMI->isStore(srcNodeOpCode)) { else if(TMI->isStore(srcNodeOpCode)) {
if(TMI->isStore(destNodeOpCode)) if(TMI->isStore(destNodeOpCode))
memInst[srcIndex]->addOutEdge(memInst[destIndex], memInst[srcIndex]->addOutEdge(memInst[destIndex],
MSchedGraphEdge::MemoryDep, MSchedGraphEdge::MemoryDep,
MSchedGraphEdge::OutputDep, 0); MSchedGraphEdge::OutputDep, 0);
else else
memInst[srcIndex]->addOutEdge(memInst[destIndex], memInst[srcIndex]->addOutEdge(memInst[destIndex],
MSchedGraphEdge::MemoryDep, MSchedGraphEdge::MemoryDep,
MSchedGraphEdge::TrueDep, 0); MSchedGraphEdge::TrueDep, 0);
} }
} }

View File

@ -36,8 +36,8 @@ using namespace llvm;
//MSchedGraphSBNode constructor //MSchedGraphSBNode constructor
MSchedGraphSBNode::MSchedGraphSBNode(const MachineInstr* inst, MSchedGraphSBNode::MSchedGraphSBNode(const MachineInstr* inst,
MSchedGraphSB *graph, unsigned idx, MSchedGraphSB *graph, unsigned idx,
unsigned late, bool isBranch) unsigned late, bool isBranch)
: Inst(inst), Parent(graph), index(idx), latency(late), : Inst(inst), Parent(graph), index(idx), latency(late),
isBranchInstr(isBranch) { isBranchInstr(isBranch) {
//Add to the graph //Add to the graph
@ -50,7 +50,7 @@ MSchedGraphSBNode::MSchedGraphSBNode(const MachineInstr* inst,
MSchedGraphSB *graph, unsigned idx, MSchedGraphSB *graph, unsigned idx,
unsigned late, bool isPNode) unsigned late, bool isPNode)
: Inst(inst), otherInstrs(other), Parent(graph), index(idx), latency(late), isPredicateNode(isPNode) { : Inst(inst), otherInstrs(other), Parent(graph), index(idx), latency(late), isPredicateNode(isPNode) {
isBranchInstr = false; isBranchInstr = false;
@ -94,7 +94,7 @@ MSchedGraphSBEdge MSchedGraphSBNode::getInEdge(MSchedGraphSBNode *pred) {
//Get the iteration difference for the edge from this node to its successor //Get the iteration difference for the edge from this node to its successor
unsigned MSchedGraphSBNode::getIteDiff(MSchedGraphSBNode *succ) { unsigned MSchedGraphSBNode::getIteDiff(MSchedGraphSBNode *succ) {
for(std::vector<MSchedGraphSBEdge>::iterator I = Successors.begin(), for(std::vector<MSchedGraphSBEdge>::iterator I = Successors.begin(),
E = Successors.end(); E = Successors.end();
I != E; ++I) { I != E; ++I) {
if(I->getDest() == succ) if(I->getDest() == succ)
@ -108,7 +108,7 @@ unsigned MSchedGraphSBNode::getInEdgeNum(MSchedGraphSBNode *pred) {
//Loop over all the successors of our predecessor //Loop over all the successors of our predecessor
//return the edge the corresponds to this in edge //return the edge the corresponds to this in edge
int count = 0; int count = 0;
for(MSchedGraphSBNode::succ_iterator I = pred->succ_begin(), for(MSchedGraphSBNode::succ_iterator I = pred->succ_begin(),
E = pred->succ_end(); E = pred->succ_end();
I != E; ++I) { I != E; ++I) {
if(*I == this) if(*I == this)
@ -129,7 +129,7 @@ bool MSchedGraphSBNode::isSuccessor(MSchedGraphSBNode *succ) {
//Dtermine if pred is a predecessor of this node //Dtermine if pred is a predecessor of this node
bool MSchedGraphSBNode::isPredecessor(MSchedGraphSBNode *pred) { bool MSchedGraphSBNode::isPredecessor(MSchedGraphSBNode *pred) {
if(std::find( Predecessors.begin(), Predecessors.end(), if(std::find( Predecessors.begin(), Predecessors.end(),
pred) != Predecessors.end()) pred) != Predecessors.end())
return true; return true;
else else
@ -167,45 +167,45 @@ void MSchedGraphSB::deleteNode(MSchedGraphSBNode *node) {
//we ignore instructions associated to the index variable since this //we ignore instructions associated to the index variable since this
//is a special case in Modulo Scheduling. We only want to deal with //is a special case in Modulo Scheduling. We only want to deal with
//the body of the loop. //the body of the loop.
MSchedGraphSB::MSchedGraphSB(std::vector<const MachineBasicBlock*> &bbs, MSchedGraphSB::MSchedGraphSB(std::vector<const MachineBasicBlock*> &bbs,
const TargetMachine &targ, const TargetMachine &targ,
std::map<const MachineInstr*, unsigned> &ignoreInstrs, std::map<const MachineInstr*, unsigned> &ignoreInstrs,
DependenceAnalyzer &DA, DependenceAnalyzer &DA,
std::map<MachineInstr*, Instruction*> &machineTollvm) std::map<MachineInstr*, Instruction*> &machineTollvm)
: BBs(bbs), Target(targ) { : BBs(bbs), Target(targ) {
//Make sure there is at least one BB and it is not null, //Make sure there is at least one BB and it is not null,
assert(((bbs.size() >= 1) && bbs[1] != NULL) && "Basic Block is null"); assert(((bbs.size() >= 1) && bbs[1] != NULL) && "Basic Block is null");
std::map<MSchedGraphSBNode*, std::set<MachineInstr*> > liveOutsideTrace; std::map<MSchedGraphSBNode*, std::set<MachineInstr*> > liveOutsideTrace;
std::set<const BasicBlock*> llvmBBs; std::set<const BasicBlock*> llvmBBs;
for(std::vector<const MachineBasicBlock*>::iterator MBB = bbs.begin(), ME = bbs.end()-1; for(std::vector<const MachineBasicBlock*>::iterator MBB = bbs.begin(), ME = bbs.end()-1;
MBB != ME; ++MBB) MBB != ME; ++MBB)
llvmBBs.insert((*MBB)->getBasicBlock()); llvmBBs.insert((*MBB)->getBasicBlock());
//create predicate nodes //create predicate nodes
DEBUG(std::cerr << "Create predicate nodes\n"); DEBUG(std::cerr << "Create predicate nodes\n");
for(std::vector<const MachineBasicBlock*>::iterator MBB = bbs.begin(), ME = bbs.end()-1; for(std::vector<const MachineBasicBlock*>::iterator MBB = bbs.begin(), ME = bbs.end()-1;
MBB != ME; ++MBB) { MBB != ME; ++MBB) {
//Get LLVM basic block //Get LLVM basic block
BasicBlock *BB = (BasicBlock*) (*MBB)->getBasicBlock(); BasicBlock *BB = (BasicBlock*) (*MBB)->getBasicBlock();
//Get Terminator //Get Terminator
BranchInst *b = dyn_cast<BranchInst>(BB->getTerminator()); BranchInst *b = dyn_cast<BranchInst>(BB->getTerminator());
std::vector<const MachineInstr*> otherInstrs; std::vector<const MachineInstr*> otherInstrs;
MachineInstr *instr = 0; MachineInstr *instr = 0;
//Get the condition for the branch (we already checked if it was conditional) //Get the condition for the branch (we already checked if it was conditional)
if(b->isConditional()) { if(b->isConditional()) {
Value *cond = b->getCondition(); Value *cond = b->getCondition();
DEBUG(std::cerr << "Condition: " << *cond << "\n"); DEBUG(std::cerr << "Condition: " << *cond << "\n");
assert(cond && "Condition must not be null!"); assert(cond && "Condition must not be null!");
if(Instruction *I = dyn_cast<Instruction>(cond)) { if(Instruction *I = dyn_cast<Instruction>(cond)) {
MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(I); MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(I);
if(tempMvec.size() > 0) { if(tempMvec.size() > 0) {
@ -217,7 +217,7 @@ MSchedGraphSB::MSchedGraphSB(std::vector<const MachineBasicBlock*> &bbs,
//Get Machine target information for calculating latency //Get Machine target information for calculating latency
const TargetInstrInfo *MTI = Target.getInstrInfo(); const TargetInstrInfo *MTI = Target.getInstrInfo();
MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(b); MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(b);
int offset = tempMvec.size(); int offset = tempMvec.size();
for (unsigned j = 0; j < tempMvec.size(); j++) { for (unsigned j = 0; j < tempMvec.size(); j++) {
@ -234,10 +234,10 @@ MSchedGraphSB::MSchedGraphSB(std::vector<const MachineBasicBlock*> &bbs,
otherInstrs.push_back(mi); otherInstrs.push_back(mi);
} }
} }
//Node is created and added to the graph automatically //Node is created and added to the graph automatically
MSchedGraphSBNode *node = new MSchedGraphSBNode(instr, otherInstrs, this, (*MBB)->size()-offset-1, 3, true); MSchedGraphSBNode *node = new MSchedGraphSBNode(instr, otherInstrs, this, (*MBB)->size()-offset-1, 3, true);
DEBUG(std::cerr << "Created Node: " << *node << "\n"); DEBUG(std::cerr << "Created Node: " << *node << "\n");
//Now loop over all instructions and see if their def is live outside the trace //Now loop over all instructions and see if their def is live outside the trace
@ -264,7 +264,7 @@ MSchedGraphSB::MSchedGraphSB(std::vector<const MachineBasicBlock*> &bbs,
} }
} }
} }
//Create nodes and edges for this BB //Create nodes and edges for this BB
@ -274,15 +274,15 @@ MSchedGraphSB::MSchedGraphSB(std::vector<const MachineBasicBlock*> &bbs,
//Copies the graph and keeps a map from old to new nodes //Copies the graph and keeps a map from old to new nodes
MSchedGraphSB::MSchedGraphSB(const MSchedGraphSB &G, MSchedGraphSB::MSchedGraphSB(const MSchedGraphSB &G,
std::map<MSchedGraphSBNode*, MSchedGraphSBNode*> &newNodes) std::map<MSchedGraphSBNode*, MSchedGraphSBNode*> &newNodes)
: Target(G.Target) { : Target(G.Target) {
BBs = G.BBs; BBs = G.BBs;
std::map<MSchedGraphSBNode*, MSchedGraphSBNode*> oldToNew; std::map<MSchedGraphSBNode*, MSchedGraphSBNode*> oldToNew;
//Copy all nodes //Copy all nodes
for(MSchedGraphSB::const_iterator N = G.GraphMap.begin(), for(MSchedGraphSB::const_iterator N = G.GraphMap.begin(),
NE = G.GraphMap.end(); N != NE; ++N) { NE = G.GraphMap.end(); N != NE; ++N) {
MSchedGraphSBNode *newNode = new MSchedGraphSBNode(*(N->second)); MSchedGraphSBNode *newNode = new MSchedGraphSBNode(*(N->second));
@ -292,7 +292,7 @@ MSchedGraphSB::MSchedGraphSB(const MSchedGraphSB &G,
} }
//Loop over nodes and update edges to point to new nodes //Loop over nodes and update edges to point to new nodes
for(MSchedGraphSB::iterator N = GraphMap.begin(), NE = GraphMap.end(); for(MSchedGraphSB::iterator N = GraphMap.begin(), NE = GraphMap.end();
N != NE; ++N) { N != NE; ++N) {
//Get the node we are dealing with //Get the node we are dealing with
@ -315,16 +315,16 @@ MSchedGraphSB::MSchedGraphSB(const MSchedGraphSB &G,
//Deconstructor, deletes all nodes in the graph //Deconstructor, deletes all nodes in the graph
MSchedGraphSB::~MSchedGraphSB () { MSchedGraphSB::~MSchedGraphSB () {
for(MSchedGraphSB::iterator I = GraphMap.begin(), E = GraphMap.end(); for(MSchedGraphSB::iterator I = GraphMap.begin(), E = GraphMap.end();
I != E; ++I) I != E; ++I)
delete I->second; delete I->second;
} }
//Print out graph //Print out graph
void MSchedGraphSB::print(std::ostream &os) const { void MSchedGraphSB::print(std::ostream &os) const {
for(MSchedGraphSB::const_iterator N = GraphMap.begin(), NE = GraphMap.end(); for(MSchedGraphSB::const_iterator N = GraphMap.begin(), NE = GraphMap.end();
N != NE; ++N) { N != NE; ++N) {
//Get the node we are dealing with //Get the node we are dealing with
MSchedGraphSBNode *node = &*(N->second); MSchedGraphSBNode *node = &*(N->second);
@ -345,9 +345,9 @@ void MSchedGraphSB::print(std::ostream &os) const {
int MSchedGraphSB::totalDelay() { int MSchedGraphSB::totalDelay() {
int sum = 0; int sum = 0;
for(MSchedGraphSB::const_iterator N = GraphMap.begin(), NE = GraphMap.end(); for(MSchedGraphSB::const_iterator N = GraphMap.begin(), NE = GraphMap.end();
N != NE; ++N) { N != NE; ++N) {
//Get the node we are dealing with //Get the node we are dealing with
MSchedGraphSBNode *node = &*(N->second); MSchedGraphSBNode *node = &*(N->second);
sum += node->getLatency(); sum += node->getLatency();
@ -357,20 +357,20 @@ int MSchedGraphSB::totalDelay() {
bool MSchedGraphSB::instrCauseException(MachineOpCode opCode) { bool MSchedGraphSB::instrCauseException(MachineOpCode opCode) {
//Check for integer divide //Check for integer divide
if(opCode == V9::SDIVXr || opCode == V9::SDIVXi if(opCode == V9::SDIVXr || opCode == V9::SDIVXi
|| opCode == V9::UDIVXr || opCode == V9::UDIVXi) || opCode == V9::UDIVXr || opCode == V9::UDIVXi)
return true; return true;
//Check for loads or stores //Check for loads or stores
const TargetInstrInfo *MTI = Target.getInstrInfo(); const TargetInstrInfo *MTI = Target.getInstrInfo();
//if( MTI->isLoad(opCode) || //if( MTI->isLoad(opCode) ||
if(MTI->isStore(opCode)) if(MTI->isStore(opCode))
return true; return true;
//Check for any floating point operation //Check for any floating point operation
const TargetSchedInfo *msi = Target.getSchedInfo(); const TargetSchedInfo *msi = Target.getSchedInfo();
InstrSchedClass sc = msi->getSchedClass(opCode); InstrSchedClass sc = msi->getSchedClass(opCode);
//FIXME: Should check for floating point instructions! //FIXME: Should check for floating point instructions!
//if(sc == SPARC_FGA || sc == SPARC_FGM) //if(sc == SPARC_FGA || sc == SPARC_FGM)
//return true; //return true;
@ -384,7 +384,7 @@ void MSchedGraphSB::buildNodesAndEdges(std::map<const MachineInstr*, unsigned> &
DependenceAnalyzer &DA, DependenceAnalyzer &DA,
std::map<MachineInstr*, Instruction*> &machineTollvm, std::map<MachineInstr*, Instruction*> &machineTollvm,
std::map<MSchedGraphSBNode*, std::set<MachineInstr*> > &liveOutsideTrace) { std::map<MSchedGraphSBNode*, std::set<MachineInstr*> > &liveOutsideTrace) {
//Get Machine target information for calculating latency //Get Machine target information for calculating latency
const TargetInstrInfo *MTI = Target.getInstrInfo(); const TargetInstrInfo *MTI = Target.getInstrInfo();
@ -398,48 +398,48 @@ void MSchedGraphSB::buildNodesAndEdges(std::map<const MachineInstr*, unsigned> &
unsigned index = 0; unsigned index = 0;
MSchedGraphSBNode *lastPred = 0; MSchedGraphSBNode *lastPred = 0;
for(std::vector<const MachineBasicBlock*>::iterator B = BBs.begin(),
for(std::vector<const MachineBasicBlock*>::iterator B = BBs.begin(),
BE = BBs.end(); B != BE; ++B) { BE = BBs.end(); B != BE; ++B) {
const MachineBasicBlock *BB = *B; const MachineBasicBlock *BB = *B;
//Loop over instructions in MBB and add nodes and edges //Loop over instructions in MBB and add nodes and edges
for (MachineBasicBlock::const_iterator MI = BB->begin(), e = BB->end(); for (MachineBasicBlock::const_iterator MI = BB->begin(), e = BB->end();
MI != e; ++MI) { MI != e; ++MI) {
//Ignore indvar instructions //Ignore indvar instructions
if(ignoreInstrs.count(MI)) { if(ignoreInstrs.count(MI)) {
++index; ++index;
continue; continue;
} }
//Get each instruction of machine basic block, get the delay //Get each instruction of machine basic block, get the delay
//using the op code, create a new node for it, and add to the //using the op code, create a new node for it, and add to the
//graph. //graph.
MachineOpCode opCode = MI->getOpcode(); MachineOpCode opCode = MI->getOpcode();
int delay; int delay;
//Get delay //Get delay
delay = MTI->maxLatency(opCode); delay = MTI->maxLatency(opCode);
//Create new node for this machine instruction and add to the graph. //Create new node for this machine instruction and add to the graph.
//Create only if not a nop //Create only if not a nop
if(MTI->isNop(opCode)) if(MTI->isNop(opCode))
continue; continue;
//Sparc BE does not use PHI opcode, so assert on this case //Sparc BE does not use PHI opcode, so assert on this case
assert(opCode != TargetInstrInfo::PHI && "Did not expect PHI opcode"); assert(opCode != TargetInstrInfo::PHI && "Did not expect PHI opcode");
bool isBranch = false; bool isBranch = false;
//Skip branches //Skip branches
if(MTI->isBranch(opCode)) if(MTI->isBranch(opCode))
continue; continue;
//Node is created and added to the graph automatically //Node is created and added to the graph automatically
MSchedGraphSBNode *node = 0; MSchedGraphSBNode *node = 0;
if(!GraphMap.count(MI)){ if(!GraphMap.count(MI)){
@ -453,7 +453,7 @@ void MSchedGraphSB::buildNodesAndEdges(std::map<const MachineInstr*, unsigned> &
if(lastPred) { if(lastPred) {
lastPred->addOutEdge(node, MSchedGraphSBEdge::PredDep, lastPred->addOutEdge(node, MSchedGraphSBEdge::PredDep,
MSchedGraphSBEdge::NonDataDep, 0); MSchedGraphSBEdge::NonDataDep, 0);
if(liveOutsideTrace.count(lastPred)) { if(liveOutsideTrace.count(lastPred)) {
for(std::set<MachineInstr*>::iterator L = liveOutsideTrace[lastPred].begin(), LE = liveOutsideTrace[lastPred].end(); L != LE; ++L) for(std::set<MachineInstr*>::iterator L = liveOutsideTrace[lastPred].begin(), LE = liveOutsideTrace[lastPred].end(); L != LE; ++L)
lastPred->addOutEdge(GraphMap[*L], MSchedGraphSBEdge::PredDep, lastPred->addOutEdge(GraphMap[*L], MSchedGraphSBEdge::PredDep,
@ -461,7 +461,7 @@ void MSchedGraphSB::buildNodesAndEdges(std::map<const MachineInstr*, unsigned> &
} }
} }
lastPred = node; lastPred = node;
} }
} }
@ -476,59 +476,59 @@ void MSchedGraphSB::buildNodesAndEdges(std::map<const MachineInstr*, unsigned> &
MSchedGraphSBEdge::NonDataDep, 0); MSchedGraphSBEdge::NonDataDep, 0);
} }
} }
//Check OpCode to keep track of memory operations to add memory //Check OpCode to keep track of memory operations to add memory
//dependencies later. //dependencies later.
if(MTI->isLoad(opCode) || MTI->isStore(opCode)) if(MTI->isLoad(opCode) || MTI->isStore(opCode))
memInstructions.push_back(node); memInstructions.push_back(node);
//Loop over all operands, and put them into the register number to //Loop over all operands, and put them into the register number to
//graph node map for determining dependencies //graph node map for determining dependencies
//If an operands is a use/def, we have an anti dependence to itself //If an operands is a use/def, we have an anti dependence to itself
for(unsigned i=0; i < MI->getNumOperands(); ++i) { for(unsigned i=0; i < MI->getNumOperands(); ++i) {
//Get Operand //Get Operand
const MachineOperand &mOp = MI->getOperand(i); const MachineOperand &mOp = MI->getOperand(i);
//Check if it has an allocated register //Check if it has an allocated register
if(mOp.hasAllocatedReg()) { if(mOp.hasAllocatedReg()) {
int regNum = mOp.getReg(); int regNum = mOp.getReg();
if(regNum != SparcV9::g0) { if(regNum != SparcV9::g0) {
//Put into our map //Put into our map
regNumtoNodeMap[regNum].push_back(std::make_pair(i, node)); regNumtoNodeMap[regNum].push_back(std::make_pair(i, node));
} }
continue; continue;
} }
//Add virtual registers dependencies //Add virtual registers dependencies
//Check if any exist in the value map already and create dependencies //Check if any exist in the value map already and create dependencies
//between them. //between them.
if(mOp.getType() == MachineOperand::MO_VirtualRegister if(mOp.getType() == MachineOperand::MO_VirtualRegister
|| mOp.getType() == MachineOperand::MO_CCRegister) { || mOp.getType() == MachineOperand::MO_CCRegister) {
//Make sure virtual register value is not null //Make sure virtual register value is not null
assert((mOp.getVRegValue() != NULL) && "Null value is defined"); assert((mOp.getVRegValue() != NULL) && "Null value is defined");
//Check if this is a read operation in a phi node, if so DO NOT PROCESS //Check if this is a read operation in a phi node, if so DO NOT PROCESS
if(mOp.isUse() && (opCode == TargetInstrInfo::PHI)) { if(mOp.isUse() && (opCode == TargetInstrInfo::PHI)) {
DEBUG(std::cerr << "Read Operation in a PHI node\n"); DEBUG(std::cerr << "Read Operation in a PHI node\n");
continue; continue;
} }
if (const Value* srcI = mOp.getVRegValue()) { if (const Value* srcI = mOp.getVRegValue()) {
//Find value in the map //Find value in the map
std::map<const Value*, std::vector<OpIndexNodePair> >::iterator V std::map<const Value*, std::vector<OpIndexNodePair> >::iterator V
= valuetoNodeMap.find(srcI); = valuetoNodeMap.find(srcI);
//If there is something in the map already, add edges from //If there is something in the map already, add edges from
//those instructions //those instructions
//to this one we are processing //to this one we are processing
if(V != valuetoNodeMap.end()) { if(V != valuetoNodeMap.end()) {
addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(), phiInstrs); addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(), phiInstrs);
//Add to value map //Add to value map
V->second.push_back(std::make_pair(i,node)); V->second.push_back(std::make_pair(i,node));
} }
@ -541,11 +541,11 @@ void MSchedGraphSB::buildNodesAndEdges(std::map<const MachineInstr*, unsigned> &
} }
++index; ++index;
} }
//Loop over LLVM BB, examine phi instructions, and add them to our //Loop over LLVM BB, examine phi instructions, and add them to our
//phiInstr list to process //phiInstr list to process
const BasicBlock *llvm_bb = BB->getBasicBlock(); const BasicBlock *llvm_bb = BB->getBasicBlock();
for(BasicBlock::const_iterator I = llvm_bb->begin(), E = llvm_bb->end(); for(BasicBlock::const_iterator I = llvm_bb->begin(), E = llvm_bb->end();
I != E; ++I) { I != E; ++I) {
if(const PHINode *PN = dyn_cast<PHINode>(I)) { if(const PHINode *PN = dyn_cast<PHINode>(I)) {
MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(PN); MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(PN);
@ -556,46 +556,46 @@ void MSchedGraphSB::buildNodesAndEdges(std::map<const MachineInstr*, unsigned> &
} }
} }
} }
} }
addMemEdges(memInstructions, DA, machineTollvm); addMemEdges(memInstructions, DA, machineTollvm);
addMachRegEdges(regNumtoNodeMap); addMachRegEdges(regNumtoNodeMap);
//Finally deal with PHI Nodes and Value* //Finally deal with PHI Nodes and Value*
for(std::vector<const MachineInstr*>::iterator I = phiInstrs.begin(), for(std::vector<const MachineInstr*>::iterator I = phiInstrs.begin(),
E = phiInstrs.end(); I != E; ++I) { E = phiInstrs.end(); I != E; ++I) {
//Get Node for this instruction //Get Node for this instruction
std::map<const MachineInstr*, MSchedGraphSBNode*>::iterator X; std::map<const MachineInstr*, MSchedGraphSBNode*>::iterator X;
X = find(*I); X = find(*I);
if(X == GraphMap.end()) if(X == GraphMap.end())
continue; continue;
MSchedGraphSBNode *node = X->second; MSchedGraphSBNode *node = X->second;
DEBUG(std::cerr << "Adding ite diff edges for node: " << *node << "\n"); DEBUG(std::cerr << "Adding ite diff edges for node: " << *node << "\n");
//Loop over operands for this instruction and add value edges //Loop over operands for this instruction and add value edges
for(unsigned i=0; i < (*I)->getNumOperands(); ++i) { for(unsigned i=0; i < (*I)->getNumOperands(); ++i) {
//Get Operand //Get Operand
const MachineOperand &mOp = (*I)->getOperand(i); const MachineOperand &mOp = (*I)->getOperand(i);
if((mOp.getType() == MachineOperand::MO_VirtualRegister if((mOp.getType() == MachineOperand::MO_VirtualRegister
|| mOp.getType() == MachineOperand::MO_CCRegister) && mOp.isUse()) { || mOp.getType() == MachineOperand::MO_CCRegister) && mOp.isUse()) {
//find the value in the map //find the value in the map
if (const Value* srcI = mOp.getVRegValue()) { if (const Value* srcI = mOp.getVRegValue()) {
//Find value in the map //Find value in the map
std::map<const Value*, std::vector<OpIndexNodePair> >::iterator V std::map<const Value*, std::vector<OpIndexNodePair> >::iterator V
= valuetoNodeMap.find(srcI); = valuetoNodeMap.find(srcI);
//If there is something in the map already, add edges from //If there is something in the map already, add edges from
//those instructions //those instructions
//to this one we are processing //to this one we are processing
if(V != valuetoNodeMap.end()) { if(V != valuetoNodeMap.end()) {
addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(), addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(),
phiInstrs, 1); phiInstrs, 1);
} }
} }
@ -648,7 +648,7 @@ void MSchedGraphSB::addMachRegEdges(std::map<int, std::vector<OpIndexNodePair> >
//Loop over all machine registers in the map, and add dependencies //Loop over all machine registers in the map, and add dependencies
//between the instructions that use it //between the instructions that use it
typedef std::map<int, std::vector<OpIndexNodePair> > regNodeMap; typedef std::map<int, std::vector<OpIndexNodePair> > regNodeMap;
for(regNodeMap::iterator I = regNumtoNodeMap.begin(); for(regNodeMap::iterator I = regNumtoNodeMap.begin();
I != regNumtoNodeMap.end(); ++I) { I != regNumtoNodeMap.end(); ++I) {
//Get the register number //Get the register number
int regNum = (*I).first; int regNum = (*I).first;
@ -675,33 +675,33 @@ void MSchedGraphSB::addMachRegEdges(std::map<int, std::vector<OpIndexNodePair> >
//Look at all instructions after this in execution order //Look at all instructions after this in execution order
for(unsigned j=i+1; j < Nodes.size(); ++j) { for(unsigned j=i+1; j < Nodes.size(); ++j) {
//Sink node is a write //Sink node is a write
if(Nodes[j].second->getInst()->getOperand(Nodes[j].first).isDef()) { if(Nodes[j].second->getInst()->getOperand(Nodes[j].first).isDef()) {
//Src only uses the register (read) //Src only uses the register (read)
if(srcIsUse) if(srcIsUse)
srcNode->addOutEdge(Nodes[j].second, srcNode->addOutEdge(Nodes[j].second,
MSchedGraphSBEdge::MachineRegister, MSchedGraphSBEdge::MachineRegister,
MSchedGraphSBEdge::AntiDep); MSchedGraphSBEdge::AntiDep);
else if(srcIsUseandDef) { else if(srcIsUseandDef) {
srcNode->addOutEdge(Nodes[j].second, srcNode->addOutEdge(Nodes[j].second,
MSchedGraphSBEdge::MachineRegister, MSchedGraphSBEdge::MachineRegister,
MSchedGraphSBEdge::AntiDep); MSchedGraphSBEdge::AntiDep);
srcNode->addOutEdge(Nodes[j].second, srcNode->addOutEdge(Nodes[j].second,
MSchedGraphSBEdge::MachineRegister, MSchedGraphSBEdge::MachineRegister,
MSchedGraphSBEdge::OutputDep); MSchedGraphSBEdge::OutputDep);
} }
else else
srcNode->addOutEdge(Nodes[j].second, srcNode->addOutEdge(Nodes[j].second,
MSchedGraphSBEdge::MachineRegister, MSchedGraphSBEdge::MachineRegister,
MSchedGraphSBEdge::OutputDep); MSchedGraphSBEdge::OutputDep);
} }
//Dest node is a read //Dest node is a read
else { else {
if(!srcIsUse || srcIsUseandDef) if(!srcIsUse || srcIsUseandDef)
srcNode->addOutEdge(Nodes[j].second, srcNode->addOutEdge(Nodes[j].second,
MSchedGraphSBEdge::MachineRegister, MSchedGraphSBEdge::MachineRegister,
MSchedGraphSBEdge::TrueDep); MSchedGraphSBEdge::TrueDep);
} }
@ -715,31 +715,31 @@ void MSchedGraphSB::addMachRegEdges(std::map<int, std::vector<OpIndexNodePair> >
if(Nodes[j].second->getInst()->getOperand(Nodes[j].first).isDef()) { if(Nodes[j].second->getInst()->getOperand(Nodes[j].first).isDef()) {
//Src only uses the register (read) //Src only uses the register (read)
if(srcIsUse) if(srcIsUse)
srcNode->addOutEdge(Nodes[j].second, srcNode->addOutEdge(Nodes[j].second,
MSchedGraphSBEdge::MachineRegister, MSchedGraphSBEdge::MachineRegister,
MSchedGraphSBEdge::AntiDep, 1); MSchedGraphSBEdge::AntiDep, 1);
else if(srcIsUseandDef) { else if(srcIsUseandDef) {
srcNode->addOutEdge(Nodes[j].second, srcNode->addOutEdge(Nodes[j].second,
MSchedGraphSBEdge::MachineRegister, MSchedGraphSBEdge::MachineRegister,
MSchedGraphSBEdge::AntiDep, 1); MSchedGraphSBEdge::AntiDep, 1);
srcNode->addOutEdge(Nodes[j].second, srcNode->addOutEdge(Nodes[j].second,
MSchedGraphSBEdge::MachineRegister, MSchedGraphSBEdge::MachineRegister,
MSchedGraphSBEdge::OutputDep, 1); MSchedGraphSBEdge::OutputDep, 1);
} }
else else
srcNode->addOutEdge(Nodes[j].second, srcNode->addOutEdge(Nodes[j].second,
MSchedGraphSBEdge::MachineRegister, MSchedGraphSBEdge::MachineRegister,
MSchedGraphSBEdge::OutputDep, 1); MSchedGraphSBEdge::OutputDep, 1);
} }
//Dest node is a read //Dest node is a read
else { else {
if(!srcIsUse || srcIsUseandDef) if(!srcIsUse || srcIsUseandDef)
srcNode->addOutEdge(Nodes[j].second, srcNode->addOutEdge(Nodes[j].second,
MSchedGraphSBEdge::MachineRegister, MSchedGraphSBEdge::MachineRegister,
MSchedGraphSBEdge::TrueDep,1 ); MSchedGraphSBEdge::TrueDep,1 );
} }
} }
@ -751,8 +751,8 @@ void MSchedGraphSB::addMachRegEdges(std::map<int, std::vector<OpIndexNodePair> >
//Add edges between all loads and stores //Add edges between all loads and stores
//Can be less strict with alias analysis and data dependence analysis. //Can be less strict with alias analysis and data dependence analysis.
void MSchedGraphSB::addMemEdges(const std::vector<MSchedGraphSBNode*>& memInst, void MSchedGraphSB::addMemEdges(const std::vector<MSchedGraphSBNode*>& memInst,
DependenceAnalyzer &DA, DependenceAnalyzer &DA,
std::map<MachineInstr*, Instruction*> &machineTollvm) { std::map<MachineInstr*, Instruction*> &machineTollvm) {
//Get Target machine instruction info //Get Target machine instruction info
@ -766,7 +766,7 @@ void MSchedGraphSB::addMemEdges(const std::vector<MSchedGraphSBNode*>& memInst,
//Get the machine opCode to determine type of memory instruction //Get the machine opCode to determine type of memory instruction
MachineOpCode srcNodeOpCode = srcInst->getOpcode(); MachineOpCode srcNodeOpCode = srcInst->getOpcode();
//All instructions after this one in execution order have an //All instructions after this one in execution order have an
//iteration delay of 0 //iteration delay of 0
for(unsigned destIndex = 0; destIndex < memInst.size(); ++destIndex) { for(unsigned destIndex = 0; destIndex < memInst.size(); ++destIndex) {
@ -779,19 +779,19 @@ void MSchedGraphSB::addMemEdges(const std::vector<MSchedGraphSBNode*>& memInst,
DEBUG(std::cerr << "MInst1: " << *srcInst << "\n"); DEBUG(std::cerr << "MInst1: " << *srcInst << "\n");
DEBUG(std::cerr << "MInst2: " << *destInst << "\n"); DEBUG(std::cerr << "MInst2: " << *destInst << "\n");
//Assuming instructions without corresponding llvm instructions //Assuming instructions without corresponding llvm instructions
//are from constant pools. //are from constant pools.
if (!machineTollvm.count(srcInst) || !machineTollvm.count(destInst)) if (!machineTollvm.count(srcInst) || !machineTollvm.count(destInst))
continue; continue;
bool useDepAnalyzer = true; bool useDepAnalyzer = true;
//Some machine loads and stores are generated by casts, so be //Some machine loads and stores are generated by casts, so be
//conservative and always add deps //conservative and always add deps
Instruction *srcLLVM = machineTollvm[srcInst]; Instruction *srcLLVM = machineTollvm[srcInst];
Instruction *destLLVM = machineTollvm[destInst]; Instruction *destLLVM = machineTollvm[destInst];
if(!isa<LoadInst>(srcLLVM) if(!isa<LoadInst>(srcLLVM)
&& !isa<StoreInst>(srcLLVM)) { && !isa<StoreInst>(srcLLVM)) {
if(isa<BinaryOperator>(srcLLVM)) { if(isa<BinaryOperator>(srcLLVM)) {
if(isa<ConstantFP>(srcLLVM->getOperand(0)) || isa<ConstantFP>(srcLLVM->getOperand(1))) if(isa<ConstantFP>(srcLLVM->getOperand(0)) || isa<ConstantFP>(srcLLVM->getOperand(1)))
@ -799,7 +799,7 @@ void MSchedGraphSB::addMemEdges(const std::vector<MSchedGraphSBNode*>& memInst,
} }
useDepAnalyzer = false; useDepAnalyzer = false;
} }
if(!isa<LoadInst>(destLLVM) if(!isa<LoadInst>(destLLVM)
&& !isa<StoreInst>(destLLVM)) { && !isa<StoreInst>(destLLVM)) {
if(isa<BinaryOperator>(destLLVM)) { if(isa<BinaryOperator>(destLLVM)) {
if(isa<ConstantFP>(destLLVM->getOperand(0)) || isa<ConstantFP>(destLLVM->getOperand(1))) if(isa<ConstantFP>(destLLVM->getOperand(0)) || isa<ConstantFP>(destLLVM->getOperand(1)))
@ -814,29 +814,29 @@ void MSchedGraphSB::addMemEdges(const std::vector<MSchedGraphSBNode*>& memInst,
if(destIndex < srcIndex) if(destIndex < srcIndex)
srcBeforeDest = false; srcBeforeDest = false;
DependenceResult dr = DA.getDependenceInfo(machineTollvm[srcInst], DependenceResult dr = DA.getDependenceInfo(machineTollvm[srcInst],
machineTollvm[destInst], machineTollvm[destInst],
srcBeforeDest); srcBeforeDest);
for(std::vector<Dependence>::iterator d = dr.dependences.begin(), for(std::vector<Dependence>::iterator d = dr.dependences.begin(),
de = dr.dependences.end(); d != de; ++d) { de = dr.dependences.end(); d != de; ++d) {
//Add edge from load to store //Add edge from load to store
memInst[srcIndex]->addOutEdge(memInst[destIndex], memInst[srcIndex]->addOutEdge(memInst[destIndex],
MSchedGraphSBEdge::MemoryDep, MSchedGraphSBEdge::MemoryDep,
d->getDepType(), d->getIteDiff()); d->getDepType(), d->getIteDiff());
} }
} }
//Otherwise, we can not do any further analysis and must make a dependence //Otherwise, we can not do any further analysis and must make a dependence
else { else {
//Get the machine opCode to determine type of memory instruction //Get the machine opCode to determine type of memory instruction
MachineOpCode destNodeOpCode = destInst->getOpcode(); MachineOpCode destNodeOpCode = destInst->getOpcode();
//Get the Value* that we are reading from the load, always the first op //Get the Value* that we are reading from the load, always the first op
const MachineOperand &mOp = srcInst->getOperand(0); const MachineOperand &mOp = srcInst->getOperand(0);
const MachineOperand &mOp2 = destInst->getOperand(0); const MachineOperand &mOp2 = destInst->getOperand(0);
if(mOp.hasAllocatedReg()) if(mOp.hasAllocatedReg())
if(mOp.getReg() == SparcV9::g0) if(mOp.getReg() == SparcV9::g0)
continue; continue;
@ -849,19 +849,19 @@ void MSchedGraphSB::addMemEdges(const std::vector<MSchedGraphSBNode*>& memInst,
if(TMI->isLoad(srcNodeOpCode)) { if(TMI->isLoad(srcNodeOpCode)) {
if(TMI->isStore(destNodeOpCode)) if(TMI->isStore(destNodeOpCode))
memInst[srcIndex]->addOutEdge(memInst[destIndex], memInst[srcIndex]->addOutEdge(memInst[destIndex],
MSchedGraphSBEdge::MemoryDep, MSchedGraphSBEdge::MemoryDep,
MSchedGraphSBEdge::AntiDep, 0); MSchedGraphSBEdge::AntiDep, 0);
} }
else if(TMI->isStore(srcNodeOpCode)) { else if(TMI->isStore(srcNodeOpCode)) {
if(TMI->isStore(destNodeOpCode)) if(TMI->isStore(destNodeOpCode))
memInst[srcIndex]->addOutEdge(memInst[destIndex], memInst[srcIndex]->addOutEdge(memInst[destIndex],
MSchedGraphSBEdge::MemoryDep, MSchedGraphSBEdge::MemoryDep,
MSchedGraphSBEdge::OutputDep, 0); MSchedGraphSBEdge::OutputDep, 0);
else else
memInst[srcIndex]->addOutEdge(memInst[destIndex], memInst[srcIndex]->addOutEdge(memInst[destIndex],
MSchedGraphSBEdge::MemoryDep, MSchedGraphSBEdge::MemoryDep,
MSchedGraphSBEdge::TrueDep, 0); MSchedGraphSBEdge::TrueDep, 0);
} }
} }

View File

@ -112,7 +112,7 @@ namespace llvm {
//Label each edge with the type of dependence //Label each edge with the type of dependence
std::string edgelabel = ""; std::string edgelabel = "";
switch (I.getEdge().getDepOrderType()) { switch (I.getEdge().getDepOrderType()) {
case MSchedGraphEdge::TrueDep: case MSchedGraphEdge::TrueDep:
edgelabel = "True"; edgelabel = "True";
break; break;
@ -120,11 +120,11 @@ namespace llvm {
case MSchedGraphEdge::AntiDep: case MSchedGraphEdge::AntiDep:
edgelabel = "Anti"; edgelabel = "Anti";
break; break;
case MSchedGraphEdge::OutputDep: case MSchedGraphEdge::OutputDep:
edgelabel = "Output"; edgelabel = "Output";
break; break;
default: default:
edgelabel = "Unknown"; edgelabel = "Unknown";
break; break;
@ -171,14 +171,14 @@ bool ModuloSchedulingPass::runOnFunction(Function &F) {
//Iterate over BasicBlocks and put them into our worklist if they are valid //Iterate over BasicBlocks and put them into our worklist if they are valid
for (MachineFunction::iterator BI = MF.begin(); BI != MF.end(); ++BI) for (MachineFunction::iterator BI = MF.begin(); BI != MF.end(); ++BI)
if(MachineBBisValid(BI)) { if(MachineBBisValid(BI)) {
if(BI->size() < 100) { if(BI->size() < 100) {
Worklist.push_back(&*BI); Worklist.push_back(&*BI);
++ValidLoops; ++ValidLoops;
} }
else else
++JumboBB; ++JumboBB;
} }
defaultInst = 0; defaultInst = 0;
@ -393,7 +393,7 @@ bool ModuloSchedulingPass::MachineBBisValid(const MachineBasicBlock *BI) {
++LoopsWithCalls; ++LoopsWithCalls;
return false; return false;
} }
//Look for conditional move //Look for conditional move
if(OC == V9::MOVRZr || OC == V9::MOVRZi || OC == V9::MOVRLEZr || OC == V9::MOVRLEZi if(OC == V9::MOVRZr || OC == V9::MOVRZi || OC == V9::MOVRLEZr || OC == V9::MOVRLEZi
|| OC == V9::MOVRLZr || OC == V9::MOVRLZi || OC == V9::MOVRNZr || OC == V9::MOVRNZi || OC == V9::MOVRLZr || OC == V9::MOVRLZi || OC == V9::MOVRNZr || OC == V9::MOVRNZi
@ -752,13 +752,13 @@ int ModuloSchedulingPass::calculateALAP(MSchedGraphNode *node, int MII,
processedOneEdge = true; processedOneEdge = true;
int succALAP = -1; int succALAP = -1;
succALAP = calculateALAP(*P, MII, maxASAP, node); succALAP = calculateALAP(*P, MII, maxASAP, node);
assert(succALAP != -1 && "Successors ALAP should have been caclulated"); assert(succALAP != -1 && "Successors ALAP should have been caclulated");
int iteDiff = P.getEdge().getIteDiff(); int iteDiff = P.getEdge().getIteDiff();
int currentSuccValue = succALAP - node->getLatency() + iteDiff * MII; int currentSuccValue = succALAP - node->getLatency() + iteDiff * MII;
DEBUG(std::cerr << "succ ALAP: " << succALAP << ", iteDiff: " << iteDiff << ", SuccLatency: " << (*P)->getLatency() << ", Current ALAP succ: " << currentSuccValue << "\n"); DEBUG(std::cerr << "succ ALAP: " << succALAP << ", iteDiff: " << iteDiff << ", SuccLatency: " << (*P)->getLatency() << ", Current ALAP succ: " << currentSuccValue << "\n");
minSuccValue = std::min(minSuccValue, currentSuccValue); minSuccValue = std::min(minSuccValue, currentSuccValue);
@ -893,7 +893,7 @@ void ModuloSchedulingPass::addReccurrence(std::vector<MSchedGraphNode*> &recurre
destBENode = recurrence[i+1]; destBENode = recurrence[i+1];
break; break;
} }
} }
} }
@ -982,7 +982,7 @@ void ModuloSchedulingPass::addRecc(std::vector<MSchedGraphNode*> &stack, std::ma
std::vector<MSchedGraphNode*> recc; std::vector<MSchedGraphNode*> recc;
//Dump recurrence for now //Dump recurrence for now
DEBUG(std::cerr << "Starting Recc\n"); DEBUG(std::cerr << "Starting Recc\n");
int totalDelay = 0; int totalDelay = 0;
int totalDistance = 0; int totalDistance = 0;
MSchedGraphNode *lastN = 0; MSchedGraphNode *lastN = 0;
@ -1015,7 +1015,7 @@ void ModuloSchedulingPass::addRecc(std::vector<MSchedGraphNode*> &stack, std::ma
DEBUG(std::cerr << "End Recc\n"); DEBUG(std::cerr << "End Recc\n");
CircCount++; CircCount++;
if(start && end) { if(start && end) {
//Insert reccurrence into the list //Insert reccurrence into the list
DEBUG(std::cerr << "Ignore Edge from!!: " << *start << " to " << *end << "\n"); DEBUG(std::cerr << "Ignore Edge from!!: " << *start << " to " << *end << "\n");
edgesToIgnore.insert(std::make_pair(newNodes[start], (newNodes[end])->getInEdgeNum(newNodes[start]))); edgesToIgnore.insert(std::make_pair(newNodes[start], (newNodes[end])->getInEdgeNum(newNodes[start])));
@ -1031,7 +1031,7 @@ void ModuloSchedulingPass::addRecc(std::vector<MSchedGraphNode*> &stack, std::ma
int value = totalDelay-(RecMII * totalDistance); int value = totalDelay-(RecMII * totalDistance);
int lastII = II; int lastII = II;
while(value < 0) { while(value < 0) {
lastII = RecMII; lastII = RecMII;
RecMII--; RecMII--;
value = totalDelay-(RecMII * totalDistance); value = totalDelay-(RecMII * totalDistance);
@ -1053,7 +1053,7 @@ void ModuloSchedulingPass::addSCC(std::vector<MSchedGraphNode*> &SCC, std::map<M
for(std::vector<MSchedGraphNode*>::iterator N = SCC.begin(), NE = SCC.end(); N != NE; ++N) { for(std::vector<MSchedGraphNode*>::iterator N = SCC.begin(), NE = SCC.end(); N != NE; ++N) {
DEBUG(std::cerr << **N << "\n"); DEBUG(std::cerr << **N << "\n");
totalDelay += (*N)->getLatency(); totalDelay += (*N)->getLatency();
for(unsigned i = 0; i < (*N)->succ_size(); ++i) { for(unsigned i = 0; i < (*N)->succ_size(); ++i) {
MSchedGraphEdge *edge = (*N)->getSuccessor(i); MSchedGraphEdge *edge = (*N)->getSuccessor(i);
if(find(SCC.begin(), SCC.end(), edge->getDest()) != SCC.end()) { if(find(SCC.begin(), SCC.end(), edge->getDest()) != SCC.end()) {
@ -1063,7 +1063,7 @@ void ModuloSchedulingPass::addSCC(std::vector<MSchedGraphNode*> &SCC, std::map<M
start = *N; start = *N;
end = edge->getDest(); end = edge->getDest();
} }
} }
} }
@ -1079,7 +1079,7 @@ void ModuloSchedulingPass::addSCC(std::vector<MSchedGraphNode*> &SCC, std::map<M
assert( (start && end) && "Must have start and end node to ignore edge for SCC"); assert( (start && end) && "Must have start and end node to ignore edge for SCC");
if(start && end) { if(start && end) {
//Insert reccurrence into the list //Insert reccurrence into the list
DEBUG(std::cerr << "Ignore Edge from!!: " << *start << " to " << *end << "\n"); DEBUG(std::cerr << "Ignore Edge from!!: " << *start << " to " << *end << "\n");
edgesToIgnore.insert(std::make_pair(newNodes[start], (newNodes[end])->getInEdgeNum(newNodes[start]))); edgesToIgnore.insert(std::make_pair(newNodes[start], (newNodes[end])->getInEdgeNum(newNodes[start])));
@ -1144,7 +1144,7 @@ void ModuloSchedulingPass::findAllCircuits(MSchedGraph *g, int II) {
if(nextSCC.size() > 1) { if(nextSCC.size() > 1) {
std::cerr << "SCC size: " << nextSCC.size() << "\n"; std::cerr << "SCC size: " << nextSCC.size() << "\n";
for(unsigned i = 0; i < nextSCC.size(); ++i) { for(unsigned i = 0; i < nextSCC.size(); ++i) {
//Loop over successor and see if in scc, then count edge //Loop over successor and see if in scc, then count edge
MSchedGraphNode *node = nextSCC[i]; MSchedGraphNode *node = nextSCC[i];
@ -1209,7 +1209,7 @@ void ModuloSchedulingPass::findAllCircuits(MSchedGraph *g, int II) {
} }
else else
break; break;
} }
DEBUG(std::cerr << "Num Circuits found: " << CircCount << "\n"); DEBUG(std::cerr << "Num Circuits found: " << CircCount << "\n");
} }
@ -1303,7 +1303,7 @@ void ModuloSchedulingPass::searchPath(MSchedGraphNode *node,
//Check if we should ignore this edge first //Check if we should ignore this edge first
if(ignoreEdge(node,*S)) if(ignoreEdge(node,*S))
continue; continue;
//check if successor is in this recurrence, we will get to it eventually //check if successor is in this recurrence, we will get to it eventually
if(new_reccurrence.count(*S)) if(new_reccurrence.count(*S))
continue; continue;
@ -1372,7 +1372,7 @@ void ModuloSchedulingPass::pathToRecc(MSchedGraphNode *node,
void ModuloSchedulingPass::computePartialOrder() { void ModuloSchedulingPass::computePartialOrder() {
TIME_REGION(X, "calculatePartialOrder"); TIME_REGION(X, "calculatePartialOrder");
DEBUG(std::cerr << "Computing Partial Order\n"); DEBUG(std::cerr << "Computing Partial Order\n");
//Only push BA branches onto the final node order, we put other //Only push BA branches onto the final node order, we put other
@ -1380,13 +1380,13 @@ void ModuloSchedulingPass::computePartialOrder() {
//it a specific order instead of relying on BA being there? //it a specific order instead of relying on BA being there?
std::vector<MSchedGraphNode*> branches; std::vector<MSchedGraphNode*> branches;
//Steps to add a recurrence to the partial order 1) Find reccurrence //Steps to add a recurrence to the partial order 1) Find reccurrence
//with the highest RecMII. Add it to the partial order. 2) For each //with the highest RecMII. Add it to the partial order. 2) For each
//recurrence with decreasing RecMII, add it to the partial order //recurrence with decreasing RecMII, add it to the partial order
//along with any nodes that connect this recurrence to recurrences //along with any nodes that connect this recurrence to recurrences
//already in the partial order //already in the partial order
for(std::set<std::pair<int, std::vector<MSchedGraphNode*> > >::reverse_iterator for(std::set<std::pair<int, std::vector<MSchedGraphNode*> > >::reverse_iterator
I = recurrenceList.rbegin(), E=recurrenceList.rend(); I !=E; ++I) { I = recurrenceList.rbegin(), E=recurrenceList.rend(); I !=E; ++I) {
std::set<MSchedGraphNode*> new_recurrence; std::set<MSchedGraphNode*> new_recurrence;
@ -1445,15 +1445,15 @@ void ModuloSchedulingPass::computePartialOrder() {
partialOrder.push_back(new_recurrence); partialOrder.push_back(new_recurrence);
//Dump out partial order //Dump out partial order
DEBUG(for(std::vector<std::set<MSchedGraphNode*> >::iterator I = partialOrder.begin(), DEBUG(for(std::vector<std::set<MSchedGraphNode*> >::iterator I = partialOrder.begin(),
E = partialOrder.end(); I !=E; ++I) { E = partialOrder.end(); I !=E; ++I) {
std::cerr << "Start set in PO\n"; std::cerr << "Start set in PO\n";
for(std::set<MSchedGraphNode*>::iterator J = I->begin(), JE = I->end(); J != JE; ++J) for(std::set<MSchedGraphNode*>::iterator J = I->begin(), JE = I->end(); J != JE; ++J)
std::cerr << "PO:" << **J << "\n"; std::cerr << "PO:" << **J << "\n";
}); });
} }
} }
@ -1530,7 +1530,7 @@ void ModuloSchedulingPass::predIntersect(std::set<MSchedGraphNode*> &CurrentSet,
//Check if we are supposed to ignore this edge or not //Check if we are supposed to ignore this edge or not
if(ignoreEdge(*P,FinalNodeOrder[j])) if(ignoreEdge(*P,FinalNodeOrder[j]))
continue; continue;
if(CurrentSet.count(*P)) if(CurrentSet.count(*P))
if(std::find(FinalNodeOrder.begin(), FinalNodeOrder.end(), *P) == FinalNodeOrder.end()) if(std::find(FinalNodeOrder.begin(), FinalNodeOrder.end(), *P) == FinalNodeOrder.end())
IntersectResult.insert(*P); IntersectResult.insert(*P);
@ -1617,7 +1617,7 @@ void ModuloSchedulingPass::orderNodes() {
//Get node attributes //Get node attributes
MSNodeAttributes nodeAttr= nodeToAttributesMap.find(*J)->second; MSNodeAttributes nodeAttr= nodeToAttributesMap.find(*J)->second;
//assert(nodeAttr != nodeToAttributesMap.end() && "Node not in attributes map!"); //assert(nodeAttr != nodeToAttributesMap.end() && "Node not in attributes map!");
if(maxASAP <= nodeAttr.ASAP) { if(maxASAP <= nodeAttr.ASAP) {
maxASAP = nodeAttr.ASAP; maxASAP = nodeAttr.ASAP;
node = *J; node = *J;
@ -1637,15 +1637,15 @@ void ModuloSchedulingPass::orderNodes() {
while(IntersectCurrent.size() > 0) { while(IntersectCurrent.size() > 0) {
DEBUG(std::cerr << "Intersection is not empty, so find heighest height\n"); DEBUG(std::cerr << "Intersection is not empty, so find heighest height\n");
int MOB = 0; int MOB = 0;
int height = 0; int height = 0;
MSchedGraphNode *highestHeightNode = *(IntersectCurrent.begin()); MSchedGraphNode *highestHeightNode = *(IntersectCurrent.begin());
//Find node in intersection with highest heigh and lowest MOB //Find node in intersection with highest heigh and lowest MOB
for(std::set<MSchedGraphNode*>::iterator I = IntersectCurrent.begin(), for(std::set<MSchedGraphNode*>::iterator I = IntersectCurrent.begin(),
E = IntersectCurrent.end(); I != E; ++I) { E = IntersectCurrent.end(); I != E; ++I) {
//Get current nodes properties //Get current nodes properties
MSNodeAttributes nodeAttr= nodeToAttributesMap.find(*I)->second; MSNodeAttributes nodeAttr= nodeToAttributesMap.find(*I)->second;
@ -1662,7 +1662,7 @@ void ModuloSchedulingPass::orderNodes() {
} }
} }
} }
//Append our node with greatest height to the NodeOrder //Append our node with greatest height to the NodeOrder
if(std::find(FinalNodeOrder.begin(), FinalNodeOrder.end(), highestHeightNode) == FinalNodeOrder.end()) { if(std::find(FinalNodeOrder.begin(), FinalNodeOrder.end(), highestHeightNode) == FinalNodeOrder.end()) {
DEBUG(std::cerr << "Adding node to Final Order: " << *highestHeightNode << "\n"); DEBUG(std::cerr << "Adding node to Final Order: " << *highestHeightNode << "\n");
@ -1695,9 +1695,9 @@ void ModuloSchedulingPass::orderNodes() {
//Reset Intersect to reflect changes in OrderNodes //Reset Intersect to reflect changes in OrderNodes
IntersectCurrent.clear(); IntersectCurrent.clear();
predIntersect(*CurrentSet, IntersectCurrent); predIntersect(*CurrentSet, IntersectCurrent);
} //End If TOP_DOWN } //End If TOP_DOWN
//Begin if BOTTOM_UP //Begin if BOTTOM_UP
else { else {
DEBUG(std::cerr << "Order is BOTTOM UP\n"); DEBUG(std::cerr << "Order is BOTTOM UP\n");
@ -1711,12 +1711,12 @@ void ModuloSchedulingPass::orderNodes() {
int MOB = 0; int MOB = 0;
int depth = 0; int depth = 0;
MSchedGraphNode *highestDepthNode = *(IntersectCurrent.begin()); MSchedGraphNode *highestDepthNode = *(IntersectCurrent.begin());
for(std::set<MSchedGraphNode*>::iterator I = IntersectCurrent.begin(), for(std::set<MSchedGraphNode*>::iterator I = IntersectCurrent.begin(),
E = IntersectCurrent.end(); I != E; ++I) { E = IntersectCurrent.end(); I != E; ++I) {
//Find node attribute in graph //Find node attribute in graph
MSNodeAttributes nodeAttr= nodeToAttributesMap.find(*I)->second; MSNodeAttributes nodeAttr= nodeToAttributesMap.find(*I)->second;
if(depth < nodeAttr.depth) { if(depth < nodeAttr.depth) {
highestDepthNode = *I; highestDepthNode = *I;
depth = nodeAttr.depth; depth = nodeAttr.depth;
@ -1730,8 +1730,8 @@ void ModuloSchedulingPass::orderNodes() {
} }
} }
} }
//Append highest depth node to the NodeOrder //Append highest depth node to the NodeOrder
if(std::find(FinalNodeOrder.begin(), FinalNodeOrder.end(), highestDepthNode) == FinalNodeOrder.end()) { if(std::find(FinalNodeOrder.begin(), FinalNodeOrder.end(), highestDepthNode) == FinalNodeOrder.end()) {
@ -1740,7 +1740,7 @@ void ModuloSchedulingPass::orderNodes() {
} }
//Remove heightestDepthNode from IntersectOrder //Remove heightestDepthNode from IntersectOrder
IntersectCurrent.erase(highestDepthNode); IntersectCurrent.erase(highestDepthNode);
//Intersect heightDepthNode's pred with CurrentSet //Intersect heightDepthNode's pred with CurrentSet
for(MSchedGraphNode::pred_iterator P = highestDepthNode->pred_begin(), for(MSchedGraphNode::pred_iterator P = highestDepthNode->pred_begin(),
@ -1748,23 +1748,23 @@ void ModuloSchedulingPass::orderNodes() {
if(CurrentSet->count(*P)) { if(CurrentSet->count(*P)) {
if(ignoreEdge(*P, highestDepthNode)) if(ignoreEdge(*P, highestDepthNode))
continue; continue;
//If not already in Intersect, add //If not already in Intersect, add
if(!IntersectCurrent.count(*P)) if(!IntersectCurrent.count(*P))
IntersectCurrent.insert(*P); IntersectCurrent.insert(*P);
} }
} }
} //End while loop over Intersect Size } //End while loop over Intersect Size
//Change order //Change order
order = TOP_DOWN; order = TOP_DOWN;
//Reset IntersectCurrent to reflect changes in OrderNodes //Reset IntersectCurrent to reflect changes in OrderNodes
IntersectCurrent.clear(); IntersectCurrent.clear();
succIntersect(*CurrentSet, IntersectCurrent); succIntersect(*CurrentSet, IntersectCurrent);
} //End if BOTTOM_DOWN } //End if BOTTOM_DOWN
DEBUG(std::cerr << "Current Intersection Size: " << IntersectCurrent.size() << "\n"); DEBUG(std::cerr << "Current Intersection Size: " << IntersectCurrent.size() << "\n");
} }
//End Wrapping while loop //End Wrapping while loop
@ -1808,7 +1808,7 @@ bool ModuloSchedulingPass::computeSchedule(const MachineBasicBlock *BB, MSchedGr
bool initialLSVal = false; bool initialLSVal = false;
bool initialESVal = false; bool initialESVal = false;
int EarlyStart = 0; int EarlyStart = 0;
int LateStart = 0; int LateStart = 0;
bool hasSucc = false; bool hasSucc = false;
bool hasPred = false; bool hasPred = false;
bool sched; bool sched;
@ -1826,10 +1826,10 @@ bool ModuloSchedulingPass::computeSchedule(const MachineBasicBlock *BB, MSchedGr
//or successors of the node we are trying to schedule //or successors of the node we are trying to schedule
for(MSSchedule::schedule_iterator nodesByCycle = schedule.begin(), nodesByCycleEnd = schedule.end(); for(MSSchedule::schedule_iterator nodesByCycle = schedule.begin(), nodesByCycleEnd = schedule.end();
nodesByCycle != nodesByCycleEnd; ++nodesByCycle) { nodesByCycle != nodesByCycleEnd; ++nodesByCycle) {
//For this cycle, get the vector of nodes schedule and loop over it //For this cycle, get the vector of nodes schedule and loop over it
for(std::vector<MSchedGraphNode*>::iterator schedNode = nodesByCycle->second.begin(), SNE = nodesByCycle->second.end(); schedNode != SNE; ++schedNode) { for(std::vector<MSchedGraphNode*>::iterator schedNode = nodesByCycle->second.begin(), SNE = nodesByCycle->second.end(); schedNode != SNE; ++schedNode) {
if((*I)->isPredecessor(*schedNode)) { if((*I)->isPredecessor(*schedNode)) {
int diff = (*I)->getInEdge(*schedNode).getIteDiff(); int diff = (*I)->getInEdge(*schedNode).getIteDiff();
int ES_Temp = nodesByCycle->first + (*schedNode)->getLatency() - diff * II; int ES_Temp = nodesByCycle->first + (*schedNode)->getLatency() - diff * II;
@ -1877,7 +1877,7 @@ bool ModuloSchedulingPass::computeSchedule(const MachineBasicBlock *BB, MSchedGr
EarlyStart = std::max(EarlyStart, ES_Temp); EarlyStart = std::max(EarlyStart, ES_Temp);
hasPred = true; hasPred = true;
} }
if((*I)->isSuccessor(*B)) { if((*I)->isSuccessor(*B)) {
int diff = (*B)->getInEdge(*I).getIteDiff(); int diff = (*B)->getInEdge(*I).getIteDiff();
int LS_Temp = (II+count-1) - (*I)->getLatency() + diff * II; int LS_Temp = (II+count-1) - (*I)->getLatency() + diff * II;
@ -1886,7 +1886,7 @@ bool ModuloSchedulingPass::computeSchedule(const MachineBasicBlock *BB, MSchedGr
LateStart = std::min(LateStart, LS_Temp); LateStart = std::min(LateStart, LS_Temp);
hasSucc = true; hasSucc = true;
} }
count--; count--;
}*/ }*/
@ -1916,7 +1916,7 @@ bool ModuloSchedulingPass::computeSchedule(const MachineBasicBlock *BB, MSchedGr
success = scheduleNode(*I, EarlyStart, EarlyStart + II - 1); success = scheduleNode(*I, EarlyStart, EarlyStart + II - 1);
if(!success) { if(!success) {
++II; ++II;
schedule.clear(); schedule.clear();
break; break;
} }
@ -1933,7 +1933,7 @@ bool ModuloSchedulingPass::computeSchedule(const MachineBasicBlock *BB, MSchedGr
} }
DEBUG(std::cerr << "Final II: " << II << "\n"); DEBUG(std::cerr << "Final II: " << II << "\n");
} }
if(II >= capII) { if(II >= capII) {
DEBUG(std::cerr << "Maximum II reached, giving up\n"); DEBUG(std::cerr << "Maximum II reached, giving up\n");
@ -2033,18 +2033,18 @@ void ModuloSchedulingPass::writePrologues(std::vector<MachineBasicBlock *> &prol
if(inKernel[j].count(&*MI)) { if(inKernel[j].count(&*MI)) {
MachineInstr *instClone = MI->clone(); MachineInstr *instClone = MI->clone();
machineBB->push_back(instClone); machineBB->push_back(instClone);
//If its a branch, insert a nop //If its a branch, insert a nop
if(mii->isBranch(instClone->getOpcode())) if(mii->isBranch(instClone->getOpcode()))
BuildMI(machineBB, V9::NOP, 0); BuildMI(machineBB, V9::NOP, 0);
DEBUG(std::cerr << "Cloning: " << *MI << "\n"); DEBUG(std::cerr << "Cloning: " << *MI << "\n");
//After cloning, we may need to save the value that this instruction defines //After cloning, we may need to save the value that this instruction defines
for(unsigned opNum=0; opNum < MI->getNumOperands(); ++opNum) { for(unsigned opNum=0; opNum < MI->getNumOperands(); ++opNum) {
Instruction *tmp; Instruction *tmp;
//get machine operand //get machine operand
MachineOperand &mOp = instClone->getOperand(opNum); MachineOperand &mOp = instClone->getOperand(opNum);
if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isDef()) { if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isDef()) {
@ -2053,18 +2053,18 @@ void ModuloSchedulingPass::writePrologues(std::vector<MachineBasicBlock *> &prol
if(valuesToSave.count(mOp.getVRegValue())) { if(valuesToSave.count(mOp.getVRegValue())) {
//Save copy in tmpInstruction //Save copy in tmpInstruction
tmp = new TmpInstruction(mOp.getVRegValue()); tmp = new TmpInstruction(mOp.getVRegValue());
//Add TmpInstruction to safe LLVM Instruction MCFI //Add TmpInstruction to safe LLVM Instruction MCFI
MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(defaultInst); MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(defaultInst);
tempMvec.addTemp((Value*) tmp); tempMvec.addTemp((Value*) tmp);
DEBUG(std::cerr << "Value: " << *(mOp.getVRegValue()) << " New Value: " << *tmp << " Stage: " << i << "\n"); DEBUG(std::cerr << "Value: " << *(mOp.getVRegValue()) << " New Value: " << *tmp << " Stage: " << i << "\n");
newValues[mOp.getVRegValue()][i]= tmp; newValues[mOp.getVRegValue()][i]= tmp;
newValLocation[tmp] = machineBB; newValLocation[tmp] = machineBB;
DEBUG(std::cerr << "Machine Instr Operands: " << *(mOp.getVRegValue()) << ", 0, " << *tmp << "\n"); DEBUG(std::cerr << "Machine Instr Operands: " << *(mOp.getVRegValue()) << ", 0, " << *tmp << "\n");
//Create machine instruction and put int machineBB //Create machine instruction and put int machineBB
MachineInstr *saveValue; MachineInstr *saveValue;
if(mOp.getVRegValue()->getType() == Type::FloatTy) if(mOp.getVRegValue()->getType() == Type::FloatTy)
@ -2073,7 +2073,7 @@ void ModuloSchedulingPass::writePrologues(std::vector<MachineBasicBlock *> &prol
saveValue = BuildMI(machineBB, V9::FMOVD, 3).addReg(mOp.getVRegValue()).addRegDef(tmp); saveValue = BuildMI(machineBB, V9::FMOVD, 3).addReg(mOp.getVRegValue()).addRegDef(tmp);
else else
saveValue = BuildMI(machineBB, V9::ORr, 3).addReg(mOp.getVRegValue()).addImm(0).addRegDef(tmp); saveValue = BuildMI(machineBB, V9::ORr, 3).addReg(mOp.getVRegValue()).addImm(0).addRegDef(tmp);
DEBUG(std::cerr << "Created new machine instr: " << *saveValue << "\n"); DEBUG(std::cerr << "Created new machine instr: " << *saveValue << "\n");
} }
@ -2161,26 +2161,26 @@ void ModuloSchedulingPass::writeEpilogues(std::vector<MachineBasicBlock *> &epil
if(inKernel[j].count(&*MI)) { if(inKernel[j].count(&*MI)) {
DEBUG(std::cerr << "Cloning instruction " << *MI << "\n"); DEBUG(std::cerr << "Cloning instruction " << *MI << "\n");
MachineInstr *clone = MI->clone(); MachineInstr *clone = MI->clone();
//Update operands that need to use the result from the phi //Update operands that need to use the result from the phi
for(unsigned opNum=0; opNum < clone->getNumOperands(); ++opNum) { for(unsigned opNum=0; opNum < clone->getNumOperands(); ++opNum) {
//get machine operand //get machine operand
const MachineOperand &mOp = clone->getOperand(opNum); const MachineOperand &mOp = clone->getOperand(opNum);
if((mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isUse())) { if((mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isUse())) {
DEBUG(std::cerr << "Writing PHI for " << (mOp.getVRegValue()) << "\n"); DEBUG(std::cerr << "Writing PHI for " << (mOp.getVRegValue()) << "\n");
//If this is the last instructions for the max iterations ago, don't update operands //If this is the last instructions for the max iterations ago, don't update operands
if(inEpilogue.count(mOp.getVRegValue())) if(inEpilogue.count(mOp.getVRegValue()))
if(inEpilogue[mOp.getVRegValue()] == i) if(inEpilogue[mOp.getVRegValue()] == i)
continue; continue;
//Quickly write appropriate phis for this operand //Quickly write appropriate phis for this operand
if(newValues.count(mOp.getVRegValue())) { if(newValues.count(mOp.getVRegValue())) {
if(newValues[mOp.getVRegValue()].count(i)) { if(newValues[mOp.getVRegValue()].count(i)) {
Instruction *tmp = new TmpInstruction(newValues[mOp.getVRegValue()][i]); Instruction *tmp = new TmpInstruction(newValues[mOp.getVRegValue()][i]);
//Get machine code for this instruction //Get machine code for this instruction
MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(defaultInst); MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(defaultInst);
tempMvec.addTemp((Value*) tmp); tempMvec.addTemp((Value*) tmp);
@ -2193,7 +2193,7 @@ void ModuloSchedulingPass::writeEpilogues(std::vector<MachineBasicBlock *> &epil
valPHIs[mOp.getVRegValue()] = tmp; valPHIs[mOp.getVRegValue()] = tmp;
} }
} }
if(valPHIs.count(mOp.getVRegValue())) { if(valPHIs.count(mOp.getVRegValue())) {
//Update the operand in the cloned instruction //Update the operand in the cloned instruction
clone->getOperand(opNum).setValueReg(valPHIs[mOp.getVRegValue()]); clone->getOperand(opNum).setValueReg(valPHIs[mOp.getVRegValue()]);
@ -2215,7 +2215,7 @@ void ModuloSchedulingPass::writeEpilogues(std::vector<MachineBasicBlock *> &epil
BL.insert(BLI,machineBB); BL.insert(BLI,machineBB);
epilogues.push_back(machineBB); epilogues.push_back(machineBB);
llvm_epilogues.push_back(llvmBB); llvm_epilogues.push_back(llvmBB);
DEBUG(std::cerr << "EPILOGUE #" << i << "\n"); DEBUG(std::cerr << "EPILOGUE #" << i << "\n");
DEBUG(machineBB->print(std::cerr)); DEBUG(machineBB->print(std::cerr));
} }
@ -2272,14 +2272,14 @@ void ModuloSchedulingPass::writeKernel(BasicBlock *llvmBB, MachineBasicBlock *ma
//Only create phi if the operand def is from a stage before this one //Only create phi if the operand def is from a stage before this one
if(schedule.defPreviousStage(mOp.getVRegValue(), I->second)) { if(schedule.defPreviousStage(mOp.getVRegValue(), I->second)) {
TmpInstruction *tmp = new TmpInstruction(mOp.getVRegValue()); TmpInstruction *tmp = new TmpInstruction(mOp.getVRegValue());
//Get machine code for this instruction //Get machine code for this instruction
MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(defaultInst); MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(defaultInst);
tempMvec.addTemp((Value*) tmp); tempMvec.addTemp((Value*) tmp);
//Update the operand in the cloned instruction //Update the operand in the cloned instruction
instClone->getOperand(i).setValueReg(tmp); instClone->getOperand(i).setValueReg(tmp);
//save this as our final phi //save this as our final phi
finalPHIValue[mOp.getVRegValue()] = tmp; finalPHIValue[mOp.getVRegValue()] = tmp;
newValLocation[tmp] = machineBB; newValLocation[tmp] = machineBB;
@ -2295,9 +2295,9 @@ void ModuloSchedulingPass::writeKernel(BasicBlock *llvmBB, MachineBasicBlock *ma
if(I->second != schedule.getMaxStage()) { if(I->second != schedule.getMaxStage()) {
if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isDef()) { if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isDef()) {
if(valuesToSave.count(mOp.getVRegValue())) { if(valuesToSave.count(mOp.getVRegValue())) {
TmpInstruction *tmp = new TmpInstruction(mOp.getVRegValue()); TmpInstruction *tmp = new TmpInstruction(mOp.getVRegValue());
//Get machine code for this instruction //Get machine code for this instruction
MachineCodeForInstruction & tempVec = MachineCodeForInstruction::get(defaultInst); MachineCodeForInstruction & tempVec = MachineCodeForInstruction::get(defaultInst);
tempVec.addTemp((Value*) tmp); tempVec.addTemp((Value*) tmp);
@ -2310,8 +2310,8 @@ void ModuloSchedulingPass::writeKernel(BasicBlock *llvmBB, MachineBasicBlock *ma
saveValue = BuildMI(machineBB, V9::FMOVD, 3).addReg(mOp.getVRegValue()).addRegDef(tmp); saveValue = BuildMI(machineBB, V9::FMOVD, 3).addReg(mOp.getVRegValue()).addRegDef(tmp);
else else
saveValue = BuildMI(machineBB, V9::ORr, 3).addReg(mOp.getVRegValue()).addImm(0).addRegDef(tmp); saveValue = BuildMI(machineBB, V9::ORr, 3).addReg(mOp.getVRegValue()).addImm(0).addRegDef(tmp);
//Save for future cleanup //Save for future cleanup
kernelValue[mOp.getVRegValue()] = tmp; kernelValue[mOp.getVRegValue()] = tmp;
newValLocation[tmp] = machineBB; newValLocation[tmp] = machineBB;
@ -2383,7 +2383,7 @@ void ModuloSchedulingPass::writeKernel(BasicBlock *llvmBB, MachineBasicBlock *ma
//Get machine code for this instruction //Get machine code for this instruction
MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(defaultInst); MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(defaultInst);
tempMvec.addTemp((Value*) tmp); tempMvec.addTemp((Value*) tmp);
MachineInstr *saveValue = BuildMI(*machineBB, machineBB->begin(), V9::PHI, 3).addReg(lastPhi).addReg(I->second).addRegDef(tmp); MachineInstr *saveValue = BuildMI(*machineBB, machineBB->begin(), V9::PHI, 3).addReg(lastPhi).addReg(I->second).addRegDef(tmp);
DEBUG(std::cerr << "Resulting PHI: " << *saveValue << "\n"); DEBUG(std::cerr << "Resulting PHI: " << *saveValue << "\n");
@ -2439,7 +2439,7 @@ void ModuloSchedulingPass::removePHIs(const MachineBasicBlock *origBB, std::vect
//Get Operand //Get Operand
const MachineOperand &mOp = I->getOperand(i); const MachineOperand &mOp = I->getOperand(i);
assert(mOp.getType() == MachineOperand::MO_VirtualRegister && "Should be a Value*\n"); assert(mOp.getType() == MachineOperand::MO_VirtualRegister && "Should be a Value*\n");
if(!tmp) { if(!tmp) {
tmp = new TmpInstruction(mOp.getVRegValue()); tmp = new TmpInstruction(mOp.getVRegValue());
addToMCFI.push_back(tmp); addToMCFI.push_back(tmp);
@ -2463,10 +2463,10 @@ void ModuloSchedulingPass::removePHIs(const MachineBasicBlock *origBB, std::vect
BuildMI(*(newValLocation[mOp.getVRegValue()]), ++inst, V9::FMOVD, 3).addReg(mOp.getVRegValue()).addRegDef(tmp); BuildMI(*(newValLocation[mOp.getVRegValue()]), ++inst, V9::FMOVD, 3).addReg(mOp.getVRegValue()).addRegDef(tmp);
else else
BuildMI(*(newValLocation[mOp.getVRegValue()]), ++inst, V9::ORr, 3).addReg(mOp.getVRegValue()).addImm(0).addRegDef(tmp); BuildMI(*(newValLocation[mOp.getVRegValue()]), ++inst, V9::ORr, 3).addReg(mOp.getVRegValue()).addImm(0).addRegDef(tmp);
break; break;
} }
} }
} }
@ -2480,11 +2480,11 @@ void ModuloSchedulingPass::removePHIs(const MachineBasicBlock *origBB, std::vect
BuildMI(*kernelBB, I, V9::FMOVD, 3).addReg(tmp).addRegDef(mOp.getVRegValue()); BuildMI(*kernelBB, I, V9::FMOVD, 3).addReg(tmp).addRegDef(mOp.getVRegValue());
else else
BuildMI(*kernelBB, I, V9::ORr, 3).addReg(tmp).addImm(0).addRegDef(mOp.getVRegValue()); BuildMI(*kernelBB, I, V9::ORr, 3).addReg(tmp).addImm(0).addRegDef(mOp.getVRegValue());
worklist.push_back(std::make_pair(kernelBB, I)); worklist.push_back(std::make_pair(kernelBB, I));
} }
} }
} }
@ -2515,12 +2515,12 @@ void ModuloSchedulingPass::removePHIs(const MachineBasicBlock *origBB, std::vect
//Get Operand //Get Operand
const MachineOperand &mOp = I->getOperand(i); const MachineOperand &mOp = I->getOperand(i);
assert(mOp.getType() == MachineOperand::MO_VirtualRegister && "Should be a Value*\n"); assert(mOp.getType() == MachineOperand::MO_VirtualRegister && "Should be a Value*\n");
if(!tmp) { if(!tmp) {
tmp = new TmpInstruction(mOp.getVRegValue()); tmp = new TmpInstruction(mOp.getVRegValue());
addToMCFI.push_back(tmp); addToMCFI.push_back(tmp);
} }
//Now for all our arguments we read, OR to the new TmpInstruction that we created //Now for all our arguments we read, OR to the new TmpInstruction that we created
if(mOp.isUse()) { if(mOp.isUse()) {
DEBUG(std::cerr << "Use: " << mOp << "\n"); DEBUG(std::cerr << "Use: " << mOp << "\n");
@ -2539,13 +2539,13 @@ void ModuloSchedulingPass::removePHIs(const MachineBasicBlock *origBB, std::vect
BuildMI(*(newValLocation[mOp.getVRegValue()]), ++inst, V9::FMOVD, 3).addReg(mOp.getVRegValue()).addRegDef(tmp); BuildMI(*(newValLocation[mOp.getVRegValue()]), ++inst, V9::FMOVD, 3).addReg(mOp.getVRegValue()).addRegDef(tmp);
else else
BuildMI(*(newValLocation[mOp.getVRegValue()]), ++inst, V9::ORr, 3).addReg(mOp.getVRegValue()).addImm(0).addRegDef(tmp); BuildMI(*(newValLocation[mOp.getVRegValue()]), ++inst, V9::ORr, 3).addReg(mOp.getVRegValue()).addImm(0).addRegDef(tmp);
break; break;
} }
} }
} }
else { else {
//Remove the phi and replace it with an OR //Remove the phi and replace it with an OR
@ -2559,7 +2559,7 @@ void ModuloSchedulingPass::removePHIs(const MachineBasicBlock *origBB, std::vect
worklist.push_back(std::make_pair(*MB,I)); worklist.push_back(std::make_pair(*MB,I));
} }
} }
} }
@ -2581,7 +2581,7 @@ void ModuloSchedulingPass::removePHIs(const MachineBasicBlock *origBB, std::vect
DEBUG(std::cerr << "Deleting PHI " << *I->second << "\n"); DEBUG(std::cerr << "Deleting PHI " << *I->second << "\n");
I->first->erase(I->second); I->first->erase(I->second);
} }
@ -2617,7 +2617,7 @@ void ModuloSchedulingPass::reconstructLoop(MachineBasicBlock *BB) {
for(unsigned i=0; i < inst->getNumOperands(); ++i) { for(unsigned i=0; i < inst->getNumOperands(); ++i) {
//get machine operand //get machine operand
const MachineOperand &mOp = inst->getOperand(i); const MachineOperand &mOp = inst->getOperand(i);
if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isUse()) { if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isUse()) {
//find the value in the map //find the value in the map
if (const Value* srcI = mOp.getVRegValue()) { if (const Value* srcI = mOp.getVRegValue()) {
@ -2629,7 +2629,7 @@ void ModuloSchedulingPass::reconstructLoop(MachineBasicBlock *BB) {
//make sure its def is not of the same stage as this instruction //make sure its def is not of the same stage as this instruction
//because it will be consumed before its used //because it will be consumed before its used
Instruction *defInst = (Instruction*) srcI; Instruction *defInst = (Instruction*) srcI;
//Should we save this value? //Should we save this value?
bool save = true; bool save = true;
@ -2638,20 +2638,20 @@ void ModuloSchedulingPass::reconstructLoop(MachineBasicBlock *BB) {
continue; continue;
MachineInstr *defInstr = defMap[srcI]; MachineInstr *defInstr = defMap[srcI];
if(lastInstrs.count(defInstr)) { if(lastInstrs.count(defInstr)) {
if(lastInstrs[defInstr] == I->second) { if(lastInstrs[defInstr] == I->second) {
save = false; save = false;
} }
} }
if(save) { if(save) {
assert(!phiUses.count(srcI) && "Did not expect to see phi use twice"); assert(!phiUses.count(srcI) && "Did not expect to see phi use twice");
if(isa<PHINode>(srcI)) if(isa<PHINode>(srcI))
phiUses[srcI] = I->second; phiUses[srcI] = I->second;
valuesToSave[srcI] = std::make_pair(I->first, i); valuesToSave[srcI] = std::make_pair(I->first, i);
} }
@ -2669,7 +2669,7 @@ void ModuloSchedulingPass::reconstructLoop(MachineBasicBlock *BB) {
} }
} }
} }
if(mOp.getType() != MachineOperand::MO_VirtualRegister && mOp.isUse()) { if(mOp.getType() != MachineOperand::MO_VirtualRegister && mOp.isUse()) {
assert("Our assumption is wrong. We have another type of register that needs to be saved\n"); assert("Our assumption is wrong. We have another type of register that needs to be saved\n");
} }
@ -2706,7 +2706,7 @@ void ModuloSchedulingPass::reconstructLoop(MachineBasicBlock *BB) {
BasicBlock *llvmKernelBB = new BasicBlock("Kernel", (Function*) (BB->getBasicBlock()->getParent())); BasicBlock *llvmKernelBB = new BasicBlock("Kernel", (Function*) (BB->getBasicBlock()->getParent()));
MachineBasicBlock *machineKernelBB = new MachineBasicBlock(llvmKernelBB); MachineBasicBlock *machineKernelBB = new MachineBasicBlock(llvmKernelBB);
MachineFunction *F = (((MachineBasicBlock*)BB)->getParent()); MachineFunction *F = (((MachineBasicBlock*)BB)->getParent());
MachineFunction::BasicBlockListType &BL = F->getBasicBlockList(); MachineFunction::BasicBlockListType &BL = F->getBasicBlockList();
MachineFunction::BasicBlockListType::iterator BLI = BB; MachineFunction::BasicBlockListType::iterator BLI = BB;
@ -2815,14 +2815,14 @@ void ModuloSchedulingPass::fixBranches(std::vector<MachineBasicBlock *> &prologu
if(TMI->isBranch(OC)) { if(TMI->isBranch(OC)) {
for(unsigned opNum = 0; opNum < mInst->getNumOperands(); ++opNum) { for(unsigned opNum = 0; opNum < mInst->getNumOperands(); ++opNum) {
MachineOperand &mOp = mInst->getOperand(opNum); MachineOperand &mOp = mInst->getOperand(opNum);
if(mOp.getType() == MachineOperand::MO_PCRelativeDisp) { if(mOp.getType() == MachineOperand::MO_PCRelativeDisp) {
if(mOp.getVRegValue() == BB->getBasicBlock()) if(mOp.getVRegValue() == BB->getBasicBlock())
mOp.setValueReg(llvmKernelBB); mOp.setValueReg(llvmKernelBB);
else else
if(llvm_epilogues.size() > 0) { if(llvm_epilogues.size() > 0) {
assert(origBranchExit == 0 && "There should only be one branch out of the loop"); assert(origBranchExit == 0 && "There should only be one branch out of the loop");
origBranchExit = mOp.getVRegValue(); origBranchExit = mOp.getVRegValue();
mOp.setValueReg(llvm_epilogues[0]); mOp.setValueReg(llvm_epilogues[0]);
} }

View File

@ -120,7 +120,7 @@ void InterferenceGraph::setInterference(const V9LiveRange *const LR1,
// return whether two live ranges interfere // return whether two live ranges interfere
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
unsigned InterferenceGraph::getInterference(const V9LiveRange *const LR1, unsigned InterferenceGraph::getInterference(const V9LiveRange *const LR1,
const V9LiveRange *const LR2) const V9LiveRange *const LR2)
const { const {
assert(LR1 != LR2); assert(LR1 != LR2);
assertIGNode(this, LR1->getUserIGNode()); assertIGNode(this, LR1->getUserIGNode());

View File

@ -791,7 +791,7 @@ PhyRegAlloc::insertCallerSavingCode(std::vector<MachineInstr*> &instrnsBefore,
// if the value is in both LV sets (i.e., live before and after // if the value is in both LV sets (i.e., live before and after
// the call machine instruction) // the call machine instruction)
unsigned Reg = MRI.getUnifiedRegNum(RCID, Color); unsigned Reg = MRI.getUnifiedRegNum(RCID, Color);
// if we haven't already pushed this register... // if we haven't already pushed this register...
if( PushedRegSet.find(Reg) == PushedRegSet.end() ) { if( PushedRegSet.find(Reg) == PushedRegSet.end() ) {
unsigned RegType = MRI.getRegTypeForLR(LR); unsigned RegType = MRI.getRegTypeForLR(LR);
@ -861,7 +861,7 @@ PhyRegAlloc::insertCallerSavingCode(std::vector<MachineInstr*> &instrnsBefore,
if (AdIAft.size() > 0) if (AdIAft.size() > 0)
instrnsAfter.insert(instrnsAfter.end(), instrnsAfter.insert(instrnsAfter.end(),
AdIAft.begin(), AdIAft.end()); AdIAft.begin(), AdIAft.end());
PushedRegSet.insert(Reg); PushedRegSet.insert(Reg);
if(DEBUG_RA) { if(DEBUG_RA) {
@ -872,7 +872,7 @@ PhyRegAlloc::insertCallerSavingCode(std::vector<MachineInstr*> &instrnsBefore,
std::cerr << " -and After:\n\t "; std::cerr << " -and After:\n\t ";
for_each(instrnsAfter.begin(), instrnsAfter.end(), for_each(instrnsAfter.begin(), instrnsAfter.end(),
std::mem_fun(&MachineInstr::dump)); std::mem_fun(&MachineInstr::dump));
} }
} // if not already pushed } // if not already pushed
} // if LR has a volatile color } // if LR has a volatile color
} // if LR has color } // if LR has color

View File

@ -11,7 +11,7 @@
// construct a forest of BURG instruction trees (class InstrForest) and then // construct a forest of BURG instruction trees (class InstrForest) and then
// uses the BURG-generated tree grammar (BURM) to find the optimal instruction // uses the BURG-generated tree grammar (BURM) to find the optimal instruction
// sequences for the SparcV9. // sequences for the SparcV9.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "MachineInstrAnnot.h" #include "MachineInstrAnnot.h"
@ -2339,7 +2339,7 @@ CreateMulConstInstruction(const TargetMachine &target, Function* F,
CreateShiftInstructions(target, F, opCode, lval, NULL, pow, CreateShiftInstructions(target, F, opCode, lval, NULL, pow,
tmpNeg, mvec, mcfi); tmpNeg, mvec, mcfi);
} }
} }
if (mvec.size() > 0 && needNeg) { if (mvec.size() > 0 && needNeg) {
@ -2883,9 +2883,9 @@ static bool CodeGenIntrinsic(Intrinsic::ID iid, CallInst &callInstr,
case Intrinsic::vacopy: case Intrinsic::vacopy:
{ {
MachineCodeForInstruction& m1 = MachineCodeForInstruction::get(&callInstr); MachineCodeForInstruction& m1 = MachineCodeForInstruction::get(&callInstr);
TmpInstruction* VReg = TmpInstruction* VReg =
new TmpInstruction(m1, callInstr.getOperand(1)->getType()); new TmpInstruction(m1, callInstr.getOperand(1)->getType());
// Simple store of current va_list (arg2) to new va_list (arg1) // Simple store of current va_list (arg2) to new va_list (arg1)
mvec.push_back(BuildMI(V9::LDXi, 3). mvec.push_back(BuildMI(V9::LDXi, 3).
addReg(callInstr.getOperand(2)).addSImm(0).addRegDef(VReg)); addReg(callInstr.getOperand(2)).addSImm(0).addRegDef(VReg));
@ -2926,7 +2926,7 @@ extern bool ThisIsAChainRule(int eruleno) {
default: default:
break; break;
} }
return false; return false;
} }
/// GetInstructionsByRule - Choose machine instructions for the /// GetInstructionsByRule - Choose machine instructions for the

View File

@ -474,7 +474,7 @@ void SparcV9RegInfo::colorMethodArgs(const Function *Meth,
cpMem2RegMI(InstrnsBefore, cpMem2RegMI(InstrnsBefore,
getFramePointer(), TmpOff, UniLRReg, regType); getFramePointer(), TmpOff, UniLRReg, regType);
} }
else { else {
cpReg2RegMI(InstrnsBefore, UniArgReg, UniLRReg, regType); cpReg2RegMI(InstrnsBefore, UniArgReg, UniLRReg, regType);
} }
} }

View File

@ -9,7 +9,7 @@
// //
// Methods of class for temporary intermediate values used within the current // Methods of class for temporary intermediate values used within the current
// SparcV9 backend. // SparcV9 backend.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "SparcV9TmpInstr.h" #include "SparcV9TmpInstr.h"

View File

@ -16,7 +16,7 @@
using namespace llvm; using namespace llvm;
TargetFrameInfo::~TargetFrameInfo() TargetFrameInfo::~TargetFrameInfo()
{ {
} }

View File

@ -2,7 +2,7 @@
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
// This file was developed by Nate Begeman and is distributed under the // This file was developed by Nate Begeman and is distributed under the
// University of Illinois Open Source License. See LICENSE.TXT for details. // University of Illinois Open Source License. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

View File

@ -102,7 +102,7 @@ void X86ATTAsmPrinter::printOp(const MachineOperand &MO, bool isCallOp) {
FnStubs.insert(Name); FnStubs.insert(Name);
O << "L" << Name << "$stub"; O << "L" << Name << "$stub";
} else if (GV->hasLinkOnceLinkage()) { } else if (GV->hasLinkOnceLinkage()) {
// Link-once, External, or Weakly-linked global variables need // Link-once, External, or Weakly-linked global variables need
// non-lazily-resolved stubs // non-lazily-resolved stubs
LinkOnceStubs.insert(Name); LinkOnceStubs.insert(Name);
O << "L" << Name << "$non_lazy_ptr"; O << "L" << Name << "$non_lazy_ptr";

View File

@ -25,7 +25,7 @@
using namespace llvm; using namespace llvm;
using namespace x86; using namespace x86;
Statistic<> llvm::x86::EmittedInsts("asm-printer", Statistic<> llvm::x86::EmittedInsts("asm-printer",
"Number of machine instrs printed"); "Number of machine instrs printed");
enum AsmWriterFlavorTy { att, intel }; enum AsmWriterFlavorTy { att, intel };
@ -58,7 +58,7 @@ bool X86SharedAsmPrinter::doInitialization(Module& M) {
leadingUnderscore = false; leadingUnderscore = false;
#endif #endif
} }
if (leadingUnderscore || forCygwin || forDarwin) if (leadingUnderscore || forCygwin || forDarwin)
GlobalPrefix = "_"; GlobalPrefix = "_";
@ -67,7 +67,7 @@ bool X86SharedAsmPrinter::doInitialization(Module& M) {
Data64bitsDirective = 0; // we can't emit a 64-bit unit Data64bitsDirective = 0; // we can't emit a 64-bit unit
ZeroDirective = "\t.space\t"; // ".space N" emits N zeros. ZeroDirective = "\t.space\t"; // ".space N" emits N zeros.
} }
return AsmPrinter::doInitialization(M); return AsmPrinter::doInitialization(M);
} }
@ -107,7 +107,7 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {
Constant *C = I->getInitializer(); Constant *C = I->getInitializer();
unsigned Size = TD.getTypeSize(C->getType()); unsigned Size = TD.getTypeSize(C->getType());
unsigned Align = TD.getTypeAlignmentShift(C->getType()); unsigned Align = TD.getTypeAlignmentShift(C->getType());
if (C->isNullValue() && if (C->isNullValue() &&
(I->hasLinkOnceLinkage() || I->hasInternalLinkage() || (I->hasLinkOnceLinkage() || I->hasInternalLinkage() ||
I->hasWeakLinkage() /* FIXME: Verify correct */)) { I->hasWeakLinkage() /* FIXME: Verify correct */)) {
@ -116,7 +116,7 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {
O << "\t.local " << name << "\n"; O << "\t.local " << name << "\n";
if (forDarwin && I->hasInternalLinkage()) if (forDarwin && I->hasInternalLinkage())
O << "\t.lcomm " << name << "," << Size << "," << Align; O << "\t.lcomm " << name << "," << Size << "," << Align;
else else
O << "\t.comm " << name << "," << Size; O << "\t.comm " << name << "," << Size;
if (!forCygwin && !forDarwin) if (!forCygwin && !forDarwin)
O << "," << (1 << Align); O << "," << (1 << Align);
@ -147,7 +147,7 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {
SwitchSection(O, CurSection, ".data"); SwitchSection(O, CurSection, ".data");
break; break;
} }
emitAlignment(Align); emitAlignment(Align);
if (!forCygwin && !forDarwin) { if (!forCygwin && !forDarwin) {
O << "\t.type " << name << ",@object\n"; O << "\t.type " << name << ",@object\n";
@ -161,7 +161,7 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {
emitGlobalConstant(C); emitGlobalConstant(C);
} }
} }
if (forDarwin) { if (forDarwin) {
// Output stubs for external global variables // Output stubs for external global variables
if (GVStubs.begin() != GVStubs.end()) if (GVStubs.begin() != GVStubs.end())
@ -191,7 +191,7 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {
} }
O << "\n"; O << "\n";
// Output stubs for link-once variables // Output stubs for link-once variables
if (LinkOnceStubs.begin() != LinkOnceStubs.end()) if (LinkOnceStubs.begin() != LinkOnceStubs.end())
O << ".data\n.align 2\n"; O << ".data\n.align 2\n";

View File

@ -105,7 +105,7 @@ namespace {
addRegisterClass(MVT::i8, X86::R8RegisterClass); addRegisterClass(MVT::i8, X86::R8RegisterClass);
addRegisterClass(MVT::i16, X86::R16RegisterClass); addRegisterClass(MVT::i16, X86::R16RegisterClass);
addRegisterClass(MVT::i32, X86::R32RegisterClass); addRegisterClass(MVT::i32, X86::R32RegisterClass);
// Promote all UINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have this // Promote all UINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have this
// operation. // operation.
setOperationAction(ISD::UINT_TO_FP , MVT::i1 , Promote); setOperationAction(ISD::UINT_TO_FP , MVT::i1 , Promote);
@ -117,10 +117,10 @@ namespace {
// this operation. // this operation.
setOperationAction(ISD::SINT_TO_FP , MVT::i1 , Promote); setOperationAction(ISD::SINT_TO_FP , MVT::i1 , Promote);
setOperationAction(ISD::SINT_TO_FP , MVT::i8 , Promote); setOperationAction(ISD::SINT_TO_FP , MVT::i8 , Promote);
// We can handle SINT_TO_FP from i64 even though i64 isn't legal. // We can handle SINT_TO_FP from i64 even though i64 isn't legal.
setOperationAction(ISD::SINT_TO_FP , MVT::i64 , Custom); setOperationAction(ISD::SINT_TO_FP , MVT::i64 , Custom);
setOperationAction(ISD::BRCONDTWOWAY , MVT::Other, Expand); setOperationAction(ISD::BRCONDTWOWAY , MVT::Other, Expand);
setOperationAction(ISD::MEMMOVE , MVT::Other, Expand); setOperationAction(ISD::MEMMOVE , MVT::Other, Expand);
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16 , Expand); setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16 , Expand);
@ -137,7 +137,7 @@ namespace {
setOperationAction(ISD::CTPOP , MVT::i32 , Expand); setOperationAction(ISD::CTPOP , MVT::i32 , Expand);
setOperationAction(ISD::CTTZ , MVT::i32 , Expand); setOperationAction(ISD::CTTZ , MVT::i32 , Expand);
setOperationAction(ISD::CTLZ , MVT::i32 , Expand); setOperationAction(ISD::CTLZ , MVT::i32 , Expand);
setOperationAction(ISD::READIO , MVT::i1 , Expand); setOperationAction(ISD::READIO , MVT::i1 , Expand);
setOperationAction(ISD::READIO , MVT::i8 , Expand); setOperationAction(ISD::READIO , MVT::i8 , Expand);
setOperationAction(ISD::READIO , MVT::i16 , Expand); setOperationAction(ISD::READIO , MVT::i16 , Expand);
@ -146,16 +146,16 @@ namespace {
setOperationAction(ISD::WRITEIO , MVT::i8 , Expand); setOperationAction(ISD::WRITEIO , MVT::i8 , Expand);
setOperationAction(ISD::WRITEIO , MVT::i16 , Expand); setOperationAction(ISD::WRITEIO , MVT::i16 , Expand);
setOperationAction(ISD::WRITEIO , MVT::i32 , Expand); setOperationAction(ISD::WRITEIO , MVT::i32 , Expand);
// These should be promoted to a larger select which is supported. // These should be promoted to a larger select which is supported.
setOperationAction(ISD::SELECT , MVT::i1 , Promote); setOperationAction(ISD::SELECT , MVT::i1 , Promote);
setOperationAction(ISD::SELECT , MVT::i8 , Promote); setOperationAction(ISD::SELECT , MVT::i8 , Promote);
if (X86ScalarSSE) { if (X86ScalarSSE) {
// Set up the FP register classes. // Set up the FP register classes.
addRegisterClass(MVT::f32, X86::RXMMRegisterClass); addRegisterClass(MVT::f32, X86::RXMMRegisterClass);
addRegisterClass(MVT::f64, X86::RXMMRegisterClass); addRegisterClass(MVT::f64, X86::RXMMRegisterClass);
// SSE has no load+extend ops // SSE has no load+extend ops
setOperationAction(ISD::EXTLOAD, MVT::f32, Expand); setOperationAction(ISD::EXTLOAD, MVT::f32, Expand);
setOperationAction(ISD::ZEXTLOAD, MVT::f32, Expand); setOperationAction(ISD::ZEXTLOAD, MVT::f32, Expand);
@ -177,12 +177,12 @@ namespace {
} else { } else {
// Set up the FP register classes. // Set up the FP register classes.
addRegisterClass(MVT::f64, X86::RFPRegisterClass); addRegisterClass(MVT::f64, X86::RFPRegisterClass);
if (!UnsafeFPMath) { if (!UnsafeFPMath) {
setOperationAction(ISD::FSIN , MVT::f64 , Expand); setOperationAction(ISD::FSIN , MVT::f64 , Expand);
setOperationAction(ISD::FCOS , MVT::f64 , Expand); setOperationAction(ISD::FCOS , MVT::f64 , Expand);
} }
addLegalFPImmediate(+0.0); // FLD0 addLegalFPImmediate(+0.0); // FLD0
addLegalFPImmediate(+1.0); // FLD1 addLegalFPImmediate(+1.0); // FLD1
addLegalFPImmediate(-0.0); // FLD0/FCHS addLegalFPImmediate(-0.0); // FLD0/FCHS
@ -195,7 +195,7 @@ namespace {
maxStoresPerMemMove = 8; // For %llvm.memmove -> sequence of stores maxStoresPerMemMove = 8; // For %llvm.memmove -> sequence of stores
allowUnalignedStores = true; // x86 supports it! allowUnalignedStores = true; // x86 supports it!
} }
// Return the number of bytes that a function should pop when it returns (in // Return the number of bytes that a function should pop when it returns (in
// addition to the space used by the return address). // addition to the space used by the return address).
// //
@ -217,7 +217,7 @@ namespace {
/// LowerCallTo - This hook lowers an abstract call to a function into an /// LowerCallTo - This hook lowers an abstract call to a function into an
/// actual call. /// actual call.
virtual std::pair<SDOperand, SDOperand> virtual std::pair<SDOperand, SDOperand>
LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, unsigned CC, LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, unsigned CC,
bool isTailCall, SDOperand Callee, ArgListTy &Args, bool isTailCall, SDOperand Callee, ArgListTy &Args,
SelectionDAG &DAG); SelectionDAG &DAG);
@ -226,7 +226,7 @@ namespace {
virtual std::pair<SDOperand,SDOperand> virtual std::pair<SDOperand,SDOperand>
LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
const Type *ArgTy, SelectionDAG &DAG); const Type *ArgTy, SelectionDAG &DAG);
virtual std::pair<SDOperand, SDOperand> virtual std::pair<SDOperand, SDOperand>
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
SelectionDAG &DAG); SelectionDAG &DAG);
@ -240,7 +240,7 @@ namespace {
LowerCCCCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, LowerCCCCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg,
bool isTailCall, bool isTailCall,
SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG); SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG);
// Fast Calling Convention implementation. // Fast Calling Convention implementation.
std::vector<SDOperand> LowerFastCCArguments(Function &F, SelectionDAG &DAG); std::vector<SDOperand> LowerFastCCArguments(Function &F, SelectionDAG &DAG);
std::pair<SDOperand, SDOperand> std::pair<SDOperand, SDOperand>
@ -259,7 +259,7 @@ X86TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
std::pair<SDOperand, SDOperand> std::pair<SDOperand, SDOperand>
X86TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, X86TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
bool isVarArg, unsigned CallingConv, bool isVarArg, unsigned CallingConv,
bool isTailCall, bool isTailCall,
SDOperand Callee, ArgListTy &Args, SDOperand Callee, ArgListTy &Args,
SelectionDAG &DAG) { SelectionDAG &DAG) {
assert((!isVarArg || CallingConv == CallingConv::C) && assert((!isVarArg || CallingConv == CallingConv::C) &&
@ -579,7 +579,7 @@ X86TargetLowering::LowerFastCCArguments(Function &F, SelectionDAG &DAG) {
unsigned ArgIncrement = 4; unsigned ArgIncrement = 4;
unsigned ObjSize = 0; unsigned ObjSize = 0;
SDOperand ArgValue; SDOperand ArgValue;
switch (ObjectVT) { switch (ObjectVT) {
default: assert(0 && "Unhandled argument type!"); default: assert(0 && "Unhandled argument type!");
case MVT::i1: case MVT::i1:
@ -1025,8 +1025,8 @@ namespace {
/// TheDAG - The DAG being selected during Select* operations. /// TheDAG - The DAG being selected during Select* operations.
SelectionDAG *TheDAG; SelectionDAG *TheDAG;
/// Subtarget - Keep a pointer to the X86Subtarget around so that we can /// Subtarget - Keep a pointer to the X86Subtarget around so that we can
/// make the right decision when generating code for different targets. /// make the right decision when generating code for different targets.
const X86Subtarget *Subtarget; const X86Subtarget *Subtarget;
public: public:
@ -1353,7 +1353,7 @@ bool ISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM) {
// the value at address GV, not the value of GV itself. This means that // the value at address GV, not the value of GV itself. This means that
// the GlobalAddress must be in the base or index register of the address, // the GlobalAddress must be in the base or index register of the address,
// not the GV offset field. // not the GV offset field.
if (Subtarget->getIndirectExternAndWeakGlobals() && if (Subtarget->getIndirectExternAndWeakGlobals() &&
(GV->hasWeakLinkage() || GV->isExternal())) { (GV->hasWeakLinkage() || GV->isExternal())) {
break; break;
} else { } else {
@ -1788,7 +1788,7 @@ void ISel::EmitSelectCC(SDOperand Cond, MVT::ValueType SVT,
// There's no SSE equivalent of FCMOVE. In some cases we can fake it up, in // There's no SSE equivalent of FCMOVE. In some cases we can fake it up, in
// Others we will have to do the PowerPC thing and generate an MBB for the // Others we will have to do the PowerPC thing and generate an MBB for the
// true and false values and select between them with a PHI. // true and false values and select between them with a PHI.
if (X86ScalarSSE && (SVT == MVT::f32 || SVT == MVT::f64)) { if (X86ScalarSSE && (SVT == MVT::f32 || SVT == MVT::f64)) {
if (0 && CondCode != NOT_SET) { if (0 && CondCode != NOT_SET) {
// FIXME: check for min and max // FIXME: check for min and max
} else { } else {
@ -1846,7 +1846,7 @@ void ISel::EmitSelectCC(SDOperand Cond, MVT::ValueType SVT,
case MVT::f64: Opc = CMOVTABFP[CondCode]; break; case MVT::f64: Opc = CMOVTABFP[CondCode]; break;
} }
} }
// Finally, if we weren't able to fold this, just emit the condition and test // Finally, if we weren't able to fold this, just emit the condition and test
// it. // it.
if (CondCode == NOT_SET || Opc == 0) { if (CondCode == NOT_SET || Opc == 0) {
@ -2186,12 +2186,12 @@ unsigned ISel::SelectExpr(SDOperand N) {
Node->dump(); Node->dump();
assert(0 && "Node not handled!\n"); assert(0 && "Node not handled!\n");
case ISD::FP_EXTEND: case ISD::FP_EXTEND:
assert(X86ScalarSSE && "Scalar SSE FP must be enabled to use f32"); assert(X86ScalarSSE && "Scalar SSE FP must be enabled to use f32");
Tmp1 = SelectExpr(N.getOperand(0)); Tmp1 = SelectExpr(N.getOperand(0));
BuildMI(BB, X86::CVTSS2SDrr, 1, Result).addReg(Tmp1); BuildMI(BB, X86::CVTSS2SDrr, 1, Result).addReg(Tmp1);
return Result; return Result;
case ISD::FP_ROUND: case ISD::FP_ROUND:
assert(X86ScalarSSE && "Scalar SSE FP must be enabled to use f32"); assert(X86ScalarSSE && "Scalar SSE FP must be enabled to use f32");
Tmp1 = SelectExpr(N.getOperand(0)); Tmp1 = SelectExpr(N.getOperand(0));
BuildMI(BB, X86::CVTSD2SSrr, 1, Result).addReg(Tmp1); BuildMI(BB, X86::CVTSD2SSrr, 1, Result).addReg(Tmp1);
return Result; return Result;
@ -2216,7 +2216,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
BuildMI(BB, X86::MOV32rr, 1, BuildMI(BB, X86::MOV32rr, 1,
Result).addReg(cast<RegSDNode>(Node)->getReg()); Result).addReg(cast<RegSDNode>(Node)->getReg());
return Result; return Result;
} }
case ISD::FrameIndex: case ISD::FrameIndex:
Tmp1 = cast<FrameIndexSDNode>(N)->getIndex(); Tmp1 = cast<FrameIndexSDNode>(N)->getIndex();
@ -2266,7 +2266,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
GlobalValue *GV = cast<GlobalAddressSDNode>(N)->getGlobal(); GlobalValue *GV = cast<GlobalAddressSDNode>(N)->getGlobal();
// For Darwin, external and weak symbols are indirect, so we want to load // For Darwin, external and weak symbols are indirect, so we want to load
// the value at address GV, not the value of GV itself. // the value at address GV, not the value of GV itself.
if (Subtarget->getIndirectExternAndWeakGlobals() && if (Subtarget->getIndirectExternAndWeakGlobals() &&
(GV->hasWeakLinkage() || GV->isExternal())) { (GV->hasWeakLinkage() || GV->isExternal())) {
BuildMI(BB, X86::MOV32rm, 4, Result).addReg(0).addZImm(1).addReg(0) BuildMI(BB, X86::MOV32rm, 4, Result).addReg(0).addZImm(1).addReg(0)
.addGlobalAddress(GV, false, 0); .addGlobalAddress(GV, false, 0);
@ -2383,7 +2383,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
BuildMI(BB, Opc, 1, Result).addReg(Tmp1); BuildMI(BB, Opc, 1, Result).addReg(Tmp1);
return Result; return Result;
} }
ContainsFPCode = true; ContainsFPCode = true;
// Spill the integer to memory and reload it from there. // Spill the integer to memory and reload it from there.
@ -2423,7 +2423,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
abort(); abort();
} }
return Result; return Result;
} }
// Change the floating point control register to use "round towards zero" // Change the floating point control register to use "round towards zero"
// mode when truncating to an integer value. // mode when truncating to an integer value.
@ -2836,8 +2836,8 @@ unsigned ISel::SelectExpr(SDOperand N) {
case MVT::i32: Opc = 7; break; case MVT::i32: Opc = 7; break;
case MVT::f32: Opc = 8; break; case MVT::f32: Opc = 8; break;
// For F64, handle promoted load operations (from F32) as well! // For F64, handle promoted load operations (from F32) as well!
case MVT::f64: case MVT::f64:
assert((!X86ScalarSSE || Op1.getOpcode() == ISD::LOAD) && assert((!X86ScalarSSE || Op1.getOpcode() == ISD::LOAD) &&
"SSE load should have been promoted"); "SSE load should have been promoted");
Opc = Op1.getOpcode() == ISD::LOAD ? 9 : 8; break; Opc = Op1.getOpcode() == ISD::LOAD ? 9 : 8; break;
} }
@ -3273,12 +3273,12 @@ unsigned ISel::SelectExpr(SDOperand N) {
case MVT::i16: Opc = X86::MOV16rm; break; case MVT::i16: Opc = X86::MOV16rm; break;
case MVT::i32: Opc = X86::MOV32rm; break; case MVT::i32: Opc = X86::MOV32rm; break;
case MVT::f32: Opc = X86::MOVSSrm; break; case MVT::f32: Opc = X86::MOVSSrm; break;
case MVT::f64: case MVT::f64:
if (X86ScalarSSE) { if (X86ScalarSSE) {
Opc = X86::MOVSDrm; Opc = X86::MOVSDrm;
} else { } else {
Opc = X86::FLD64m; Opc = X86::FLD64m;
ContainsFPCode = true; ContainsFPCode = true;
} }
break; break;
} }
@ -3497,7 +3497,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
unsigned RegOp1 = SelectExpr(N.getOperand(4)); unsigned RegOp1 = SelectExpr(N.getOperand(4));
unsigned RegOp2 = unsigned RegOp2 =
Node->getNumOperands() > 5 ? SelectExpr(N.getOperand(5)) : 0; Node->getNumOperands() > 5 ? SelectExpr(N.getOperand(5)) : 0;
switch (N.getOperand(4).getValueType()) { switch (N.getOperand(4).getValueType()) {
default: assert(0 && "Bad thing to pass in regs"); default: assert(0 && "Bad thing to pass in regs");
case MVT::i1: case MVT::i1:
@ -3595,7 +3595,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
assert(0 && "readport already emitted!?"); assert(0 && "readport already emitted!?");
} else } else
Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType()); Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
Select(Node->getOperand(0)); // Select the chain. Select(Node->getOperand(0)); // Select the chain.
// If the port is a single-byte constant, use the immediate form. // If the port is a single-byte constant, use the immediate form.
@ -3640,7 +3640,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
std::cerr << "Cannot do input on this data type"; std::cerr << "Cannot do input on this data type";
exit(1); exit(1);
} }
} }
return 0; return 0;
@ -4066,7 +4066,7 @@ void ISel::EmitFastCCToFastCCTailCall(SDNode *TailCallNode) {
RegOp1 = SelectExpr(TailCallNode->getOperand(4)); RegOp1 = SelectExpr(TailCallNode->getOperand(4));
if (TailCallNode->getNumOperands() > 5) if (TailCallNode->getNumOperands() > 5)
RegOp2 = SelectExpr(TailCallNode->getOperand(5)); RegOp2 = SelectExpr(TailCallNode->getOperand(5));
switch (TailCallNode->getOperand(4).getValueType()) { switch (TailCallNode->getOperand(4).getValueType()) {
default: assert(0 && "Bad thing to pass in regs"); default: assert(0 && "Bad thing to pass in regs");
case MVT::i1: case MVT::i1:
@ -4167,12 +4167,12 @@ void ISel::Select(SDOperand N) {
case MVT::i16: Opc = X86::MOV16rr; break; case MVT::i16: Opc = X86::MOV16rr; break;
case MVT::i32: Opc = X86::MOV32rr; break; case MVT::i32: Opc = X86::MOV32rr; break;
case MVT::f32: Opc = X86::MOVAPSrr; break; case MVT::f32: Opc = X86::MOVAPSrr; break;
case MVT::f64: case MVT::f64:
if (X86ScalarSSE) { if (X86ScalarSSE) {
Opc = X86::MOVAPDrr; Opc = X86::MOVAPDrr;
} else { } else {
Opc = X86::FpMOV; Opc = X86::FpMOV;
ContainsFPCode = true; ContainsFPCode = true;
} }
break; break;
} }
@ -4191,8 +4191,8 @@ void ISel::Select(SDOperand N) {
assert(0 && "Unknown return instruction!"); assert(0 && "Unknown return instruction!");
case 3: case 3:
assert(N.getOperand(1).getValueType() == MVT::i32 && assert(N.getOperand(1).getValueType() == MVT::i32 &&
N.getOperand(2).getValueType() == MVT::i32 && N.getOperand(2).getValueType() == MVT::i32 &&
"Unknown two-register value!"); "Unknown two-register value!");
if (getRegPressure(N.getOperand(1)) > getRegPressure(N.getOperand(2))) { if (getRegPressure(N.getOperand(1)) > getRegPressure(N.getOperand(2))) {
Tmp1 = SelectExpr(N.getOperand(1)); Tmp1 = SelectExpr(N.getOperand(1));
Tmp2 = SelectExpr(N.getOperand(2)); Tmp2 = SelectExpr(N.getOperand(2));
@ -4224,7 +4224,7 @@ void ISel::Select(SDOperand N) {
addFrameReference(BuildMI(BB, X86::MOVSSmr, 5), FrameIdx).addReg(Tmp1); addFrameReference(BuildMI(BB, X86::MOVSSmr, 5), FrameIdx).addReg(Tmp1);
addFrameReference(BuildMI(BB, X86::FLD32m, 4, X86::FP0), FrameIdx); addFrameReference(BuildMI(BB, X86::FLD32m, 4, X86::FP0), FrameIdx);
BuildMI(BB, X86::FpSETRESULT, 1).addReg(X86::FP0); BuildMI(BB, X86::FpSETRESULT, 1).addReg(X86::FP0);
ContainsFPCode = true; ContainsFPCode = true;
} else { } else {
assert(0 && "MVT::f32 only legal with scalar sse fp"); assert(0 && "MVT::f32 only legal with scalar sse fp");
abort(); abort();
@ -4239,7 +4239,7 @@ void ISel::Select(SDOperand N) {
addFrameReference(BuildMI(BB, X86::MOVSDmr, 5), FrameIdx).addReg(Tmp1); addFrameReference(BuildMI(BB, X86::MOVSDmr, 5), FrameIdx).addReg(Tmp1);
addFrameReference(BuildMI(BB, X86::FLD64m, 4, X86::FP0), FrameIdx); addFrameReference(BuildMI(BB, X86::FLD64m, 4, X86::FP0), FrameIdx);
BuildMI(BB, X86::FpSETRESULT, 1).addReg(X86::FP0); BuildMI(BB, X86::FpSETRESULT, 1).addReg(X86::FP0);
ContainsFPCode = true; ContainsFPCode = true;
} else { } else {
BuildMI(BB, X86::FpSETRESULT, 1).addReg(Tmp1); BuildMI(BB, X86::FpSETRESULT, 1).addReg(Tmp1);
} }
@ -4367,7 +4367,7 @@ void ISel::Select(SDOperand N) {
default: assert(0 && "Cannot truncstore this type!"); default: assert(0 && "Cannot truncstore this type!");
case MVT::i1: Opc = X86::MOV8mr; break; case MVT::i1: Opc = X86::MOV8mr; break;
case MVT::f32: case MVT::f32:
assert(!X86ScalarSSE && "Cannot truncstore scalar SSE regs"); assert(!X86ScalarSSE && "Cannot truncstore scalar SSE regs");
Opc = X86::FST32m; break; Opc = X86::FST32m; break;
} }
@ -4426,7 +4426,7 @@ void ISel::Select(SDOperand N) {
GlobalValue *GV = GA->getGlobal(); GlobalValue *GV = GA->getGlobal();
// For Darwin, external and weak symbols are indirect, so we want to load // For Darwin, external and weak symbols are indirect, so we want to load
// the value at address GV, not the value of GV itself. // the value at address GV, not the value of GV itself.
if (Subtarget->getIndirectExternAndWeakGlobals() && if (Subtarget->getIndirectExternAndWeakGlobals() &&
(GV->hasWeakLinkage() || GV->isExternal())) { (GV->hasWeakLinkage() || GV->isExternal())) {
Tmp1 = MakeReg(MVT::i32); Tmp1 = MakeReg(MVT::i32);
BuildMI(BB, X86::MOV32rm, 4, Tmp1).addReg(0).addZImm(1).addReg(0) BuildMI(BB, X86::MOV32rm, 4, Tmp1).addReg(0).addZImm(1).addReg(0)

View File

@ -3510,7 +3510,7 @@ void X86ISel::emitCastOperation(MachineBasicBlock *BB,
unsigned FltAlign = TM.getTargetData().getFloatAlignment(); unsigned FltAlign = TM.getTargetData().getFloatAlignment();
int FrameIdx = F->getFrameInfo()->CreateStackObject(4, FltAlign); int FrameIdx = F->getFrameInfo()->CreateStackObject(4, FltAlign);
addFrameReference(BuildMI(*BB, IP, X86::FST32m, 5), addFrameReference(BuildMI(*BB, IP, X86::FST32m, 5),
FrameIdx).addReg(SrcReg); FrameIdx).addReg(SrcReg);
addFrameReference(BuildMI(*BB, IP, X86::FLD32m, 5, DestReg), FrameIdx); addFrameReference(BuildMI(*BB, IP, X86::FLD32m, 5, DestReg), FrameIdx);
} }
} else if (SrcClass == cLong) { } else if (SrcClass == cLong) {

View File

@ -30,7 +30,7 @@ namespace {
virtual bool runOnMachineFunction(MachineFunction &MF); virtual bool runOnMachineFunction(MachineFunction &MF);
bool PeepholeOptimize(MachineBasicBlock &MBB, bool PeepholeOptimize(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &I); MachineBasicBlock::iterator &I);
virtual const char *getPassName() const { return "X86 Peephole Optimizer"; } virtual const char *getPassName() const { return "X86 Peephole Optimizer"; }
}; };
@ -44,17 +44,17 @@ bool PH::runOnMachineFunction(MachineFunction &MF) {
for (MachineFunction::iterator BI = MF.begin(), E = MF.end(); BI != E; ++BI) for (MachineFunction::iterator BI = MF.begin(), E = MF.end(); BI != E; ++BI)
for (MachineBasicBlock::iterator I = BI->begin(); I != BI->end(); ) for (MachineBasicBlock::iterator I = BI->begin(); I != BI->end(); )
if (PeepholeOptimize(*BI, I)) { if (PeepholeOptimize(*BI, I)) {
Changed = true; Changed = true;
++NumPHOpts; ++NumPHOpts;
} else } else
++I; ++I;
return Changed; return Changed;
} }
bool PH::PeepholeOptimize(MachineBasicBlock &MBB, bool PH::PeepholeOptimize(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &I) { MachineBasicBlock::iterator &I) {
assert(I != MBB.end()); assert(I != MBB.end());
MachineBasicBlock::iterator NextI = next(I); MachineBasicBlock::iterator NextI = next(I);
@ -218,20 +218,20 @@ bool PH::PeepholeOptimize(MachineBasicBlock &MBB,
if (MI->getOperand(1).isImmediate()) { // avoid mov EAX, <value> if (MI->getOperand(1).isImmediate()) { // avoid mov EAX, <value>
int Val = MI->getOperand(1).getImmedValue(); int Val = MI->getOperand(1).getImmedValue();
if (Val == 0) { // mov EAX, 0 -> xor EAX, EAX if (Val == 0) { // mov EAX, 0 -> xor EAX, EAX
static const unsigned Opcode[] ={X86::XOR8rr,X86::XOR16rr,X86::XOR32rr}; static const unsigned Opcode[] ={X86::XOR8rr,X86::XOR16rr,X86::XOR32rr};
unsigned Reg = MI->getOperand(0).getReg(); unsigned Reg = MI->getOperand(0).getReg();
I = MBB.insert(MBB.erase(I), I = MBB.insert(MBB.erase(I),
BuildMI(Opcode[Size], 2, Reg).addReg(Reg).addReg(Reg)); BuildMI(Opcode[Size], 2, Reg).addReg(Reg).addReg(Reg));
return true; return true;
} else if (Val == -1) { // mov EAX, -1 -> or EAX, -1 } else if (Val == -1) { // mov EAX, -1 -> or EAX, -1
// TODO: 'or Reg, -1' has a smaller encoding than 'mov Reg, -1' // TODO: 'or Reg, -1' has a smaller encoding than 'mov Reg, -1'
} }
} }
return false; return false;
#endif #endif
case X86::BSWAP32r: // Change bswap EAX, bswap EAX into nothing case X86::BSWAP32r: // Change bswap EAX, bswap EAX into nothing
if (Next->getOpcode() == X86::BSWAP32r && if (Next->getOpcode() == X86::BSWAP32r &&
MI->getOperand(0).getReg() == Next->getOperand(0).getReg()) { MI->getOperand(0).getReg() == Next->getOperand(0).getReg()) {
I = MBB.erase(MBB.erase(I)); I = MBB.erase(MBB.erase(I));
return true; return true;
} }
@ -314,7 +314,7 @@ namespace {
virtual bool runOnMachineFunction(MachineFunction &MF); virtual bool runOnMachineFunction(MachineFunction &MF);
bool PeepholeOptimize(MachineBasicBlock &MBB, bool PeepholeOptimize(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &I); MachineBasicBlock::iterator &I);
virtual const char *getPassName() const { virtual const char *getPassName() const {
return "X86 SSA-based Peephole Optimizer"; return "X86 SSA-based Peephole Optimizer";

View File

@ -387,10 +387,10 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineInstr *New = 0; MachineInstr *New = 0;
if (Old->getOpcode() == X86::ADJCALLSTACKDOWN) { if (Old->getOpcode() == X86::ADJCALLSTACKDOWN) {
New=BuildMI(X86::SUB32ri, 1, X86::ESP, MachineOperand::UseAndDef) New=BuildMI(X86::SUB32ri, 1, X86::ESP, MachineOperand::UseAndDef)
.addZImm(Amount); .addZImm(Amount);
} else { } else {
assert(Old->getOpcode() == X86::ADJCALLSTACKUP); assert(Old->getOpcode() == X86::ADJCALLSTACKUP);
// factor out the amount the callee already popped. // factor out the amount the callee already popped.
unsigned CalleeAmt = Old->getOperand(1).getImmedValue(); unsigned CalleeAmt = Old->getOperand(1).getImmedValue();
Amount -= CalleeAmt; Amount -= CalleeAmt;
@ -407,7 +407,7 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
// something off the stack pointer, add it back. We do this until we have // something off the stack pointer, add it back. We do this until we have
// more advanced stack pointer tracking ability. // more advanced stack pointer tracking ability.
if (unsigned CalleeAmt = I->getOperand(1).getImmedValue()) { if (unsigned CalleeAmt = I->getOperand(1).getImmedValue()) {
MachineInstr *New = MachineInstr *New =
BuildMI(X86::SUB32ri, 1, X86::ESP, BuildMI(X86::SUB32ri, 1, X86::ESP,
MachineOperand::UseAndDef).addZImm(CalleeAmt); MachineOperand::UseAndDef).addZImm(CalleeAmt);
MBB.insert(I, New); MBB.insert(I, New);
@ -475,7 +475,7 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
// Save EBP into the appropriate stack slot... // Save EBP into the appropriate stack slot...
MI = addRegOffset(BuildMI(X86::MOV32mr, 5), // mov [ESP-<offset>], EBP MI = addRegOffset(BuildMI(X86::MOV32mr, 5), // mov [ESP-<offset>], EBP
X86::ESP, EBPOffset+NumBytes).addReg(X86::EBP); X86::ESP, EBPOffset+NumBytes).addReg(X86::EBP);
MBB.insert(MBBI, MI); MBB.insert(MBBI, MI);
// Update EBP with the new base value... // Update EBP with the new base value...

View File

@ -15,8 +15,8 @@
#include "llvm/Module.h" #include "llvm/Module.h"
using namespace llvm; using namespace llvm;
X86Subtarget::X86Subtarget(const Module &M) X86Subtarget::X86Subtarget(const Module &M)
: TargetSubtarget(), stackAlignment(8), : TargetSubtarget(), stackAlignment(8),
indirectExternAndWeakGlobals(false), asmDarwinLinkerStubs(false), indirectExternAndWeakGlobals(false), asmDarwinLinkerStubs(false),
asmLeadingUnderscore(false), asmAlignmentIsInBytes(false), asmLeadingUnderscore(false), asmAlignmentIsInBytes(false),
asmPrintDotLocalConstants(false), asmPrintDotLCommConstants(false), asmPrintDotLocalConstants(false), asmPrintDotLCommConstants(false),
@ -25,7 +25,7 @@ X86Subtarget::X86Subtarget(const Module &M)
bool forCygwin = false; bool forCygwin = false;
bool forDarwin = false; bool forDarwin = false;
bool forWindows = false; bool forWindows = false;
// Set the boolean corresponding to the current target triple, or the default // Set the boolean corresponding to the current target triple, or the default
// if one cannot be determined, to true. // if one cannot be determined, to true.
const std::string& TT = M.getTargetTriple(); const std::string& TT = M.getTargetTriple();

View File

@ -105,7 +105,7 @@ X86TargetMachine::X86TargetMachine(const Module &M, IntrinsicLowering *IL)
// does to emit statically compiled machine code. // does to emit statically compiled machine code.
bool X86TargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &Out, bool X86TargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &Out,
CodeGenFileType FileType) { CodeGenFileType FileType) {
if (FileType != TargetMachine::AssemblyFile && if (FileType != TargetMachine::AssemblyFile &&
FileType != TargetMachine::ObjectFile) return true; FileType != TargetMachine::ObjectFile) return true;
// FIXME: Implement efficient support for garbage collection intrinsics. // FIXME: Implement efficient support for garbage collection intrinsics.

View File

@ -149,24 +149,24 @@ bool PruneEH::SimplifyFunction(Function *F) {
II->op_end()), II->op_end()),
Name, II); Name, II);
Call->setCallingConv(II->getCallingConv()); Call->setCallingConv(II->getCallingConv());
// Anything that used the value produced by the invoke instruction // Anything that used the value produced by the invoke instruction
// now uses the value produced by the call instruction. // now uses the value produced by the call instruction.
II->replaceAllUsesWith(Call); II->replaceAllUsesWith(Call);
BasicBlock *UnwindBlock = II->getUnwindDest(); BasicBlock *UnwindBlock = II->getUnwindDest();
UnwindBlock->removePredecessor(II->getParent()); UnwindBlock->removePredecessor(II->getParent());
// Insert a branch to the normal destination right before the // Insert a branch to the normal destination right before the
// invoke. // invoke.
new BranchInst(II->getNormalDest(), II); new BranchInst(II->getNormalDest(), II);
// Finally, delete the invoke instruction! // Finally, delete the invoke instruction!
BB->getInstList().pop_back(); BB->getInstList().pop_back();
// If the unwind block is now dead, nuke it. // If the unwind block is now dead, nuke it.
if (pred_begin(UnwindBlock) == pred_end(UnwindBlock)) if (pred_begin(UnwindBlock) == pred_end(UnwindBlock))
DeleteBasicBlock(UnwindBlock); // Delete the new BB. DeleteBasicBlock(UnwindBlock); // Delete the new BB.
++NumRemoved; ++NumRemoved;
MadeChange = true; MadeChange = true;
} }
@ -221,6 +221,6 @@ void PruneEH::DeleteBasicBlock(BasicBlock *BB) {
for (unsigned i = 0, e = Succs.size(); i != e; ++i) for (unsigned i = 0, e = Succs.size(); i != e; ++i)
Succs[i]->removePredecessor(BB); Succs[i]->removePredecessor(BB);
BB->eraseFromParent(); BB->eraseFromParent();
} }

View File

@ -2,18 +2,18 @@
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
// This file was developed by Reid Spencer and is distributed under the // This file was developed by Reid Spencer and is distributed under the
// University of Illinois Open Source License. See LICENSE.TXT for details. // University of Illinois Open Source License. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
// This file implements a module pass that applies a variety of small // This file implements a module pass that applies a variety of small
// optimizations for calls to specific well-known function calls (e.g. runtime // optimizations for calls to specific well-known function calls (e.g. runtime
// library functions). For example, a call to the function "exit(3)" that // library functions). For example, a call to the function "exit(3)" that
// occurs within the main() function can be transformed into a simple "return 3" // occurs within the main() function can be transformed into a simple "return 3"
// instruction. Any optimization that takes this form (replace call to library // instruction. Any optimization that takes this form (replace call to library
// function with simpler code that provides the same result) belongs in this // function with simpler code that provides the same result) belongs in this
// file. // file.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -35,7 +35,7 @@ namespace {
/// This statistic keeps track of the total number of library calls that have /// This statistic keeps track of the total number of library calls that have
/// been simplified regardless of which call it is. /// been simplified regardless of which call it is.
Statistic<> SimplifiedLibCalls("simplify-libcalls", Statistic<> SimplifiedLibCalls("simplify-libcalls",
"Total number of library calls simplified"); "Total number of library calls simplified");
// Forward declarations // Forward declarations
@ -53,21 +53,21 @@ static hash_map<std::string,LibCallOptimization*> optlist;
/// corresponds to one library call. The SimplifyLibCalls pass will call the /// corresponds to one library call. The SimplifyLibCalls pass will call the
/// ValidateCalledFunction method to ask the optimization if a given Function /// ValidateCalledFunction method to ask the optimization if a given Function
/// is the kind that the optimization can handle. If the subclass returns true, /// is the kind that the optimization can handle. If the subclass returns true,
/// then SImplifyLibCalls will also call the OptimizeCall method to perform, /// then SImplifyLibCalls will also call the OptimizeCall method to perform,
/// or attempt to perform, the optimization(s) for the library call. Otherwise, /// or attempt to perform, the optimization(s) for the library call. Otherwise,
/// OptimizeCall won't be called. Subclasses are responsible for providing the /// OptimizeCall won't be called. Subclasses are responsible for providing the
/// name of the library call (strlen, strcpy, etc.) to the LibCallOptimization /// name of the library call (strlen, strcpy, etc.) to the LibCallOptimization
/// constructor. This is used to efficiently select which call instructions to /// constructor. This is used to efficiently select which call instructions to
/// optimize. The criteria for a "lib call" is "anything with well known /// optimize. The criteria for a "lib call" is "anything with well known
/// semantics", typically a library function that is defined by an international /// semantics", typically a library function that is defined by an international
/// standard. Because the semantics are well known, the optimizations can /// standard. Because the semantics are well known, the optimizations can
/// generally short-circuit actually calling the function if there's a simpler /// generally short-circuit actually calling the function if there's a simpler
/// way (e.g. strlen(X) can be reduced to a constant if X is a constant global). /// way (e.g. strlen(X) can be reduced to a constant if X is a constant global).
/// @brief Base class for library call optimizations /// @brief Base class for library call optimizations
class LibCallOptimization class LibCallOptimization
{ {
public: public:
/// The \p fname argument must be the name of the library function being /// The \p fname argument must be the name of the library function being
/// optimized by the subclass. /// optimized by the subclass.
/// @brief Constructor that registers the optimization. /// @brief Constructor that registers the optimization.
LibCallOptimization(const char* fname, const char* description ) LibCallOptimization(const char* fname, const char* description )
@ -84,12 +84,12 @@ public:
virtual ~LibCallOptimization() { optlist.erase(func_name); } virtual ~LibCallOptimization() { optlist.erase(func_name); }
/// The implementation of this function in subclasses should determine if /// The implementation of this function in subclasses should determine if
/// \p F is suitable for the optimization. This method is called by /// \p F is suitable for the optimization. This method is called by
/// SimplifyLibCalls::runOnModule to short circuit visiting all the call /// SimplifyLibCalls::runOnModule to short circuit visiting all the call
/// sites of such a function if that function is not suitable in the first /// sites of such a function if that function is not suitable in the first
/// place. If the called function is suitabe, this method should return true; /// place. If the called function is suitabe, this method should return true;
/// false, otherwise. This function should also perform any lazy /// false, otherwise. This function should also perform any lazy
/// initialization that the LibCallOptimization needs to do, if its to return /// initialization that the LibCallOptimization needs to do, if its to return
/// true. This avoids doing initialization until the optimizer is actually /// true. This avoids doing initialization until the optimizer is actually
/// going to be called upon to do some optimization. /// going to be called upon to do some optimization.
/// @brief Determine if the function is suitable for optimization /// @brief Determine if the function is suitable for optimization
@ -98,10 +98,10 @@ public:
SimplifyLibCalls& SLC ///< The pass object invoking us SimplifyLibCalls& SLC ///< The pass object invoking us
) = 0; ) = 0;
/// The implementations of this function in subclasses is the heart of the /// The implementations of this function in subclasses is the heart of the
/// SimplifyLibCalls algorithm. Sublcasses of this class implement /// SimplifyLibCalls algorithm. Sublcasses of this class implement
/// OptimizeCall to determine if (a) the conditions are right for optimizing /// OptimizeCall to determine if (a) the conditions are right for optimizing
/// the call and (b) to perform the optimization. If an action is taken /// the call and (b) to perform the optimization. If an action is taken
/// against ci, the subclass is responsible for returning true and ensuring /// against ci, the subclass is responsible for returning true and ensuring
/// that ci is erased from its parent. /// that ci is erased from its parent.
/// @brief Optimize a call, if possible. /// @brief Optimize a call, if possible.
@ -125,15 +125,15 @@ private:
#endif #endif
}; };
/// This class is an LLVM Pass that applies each of the LibCallOptimization /// This class is an LLVM Pass that applies each of the LibCallOptimization
/// instances to all the call sites in a module, relatively efficiently. The /// instances to all the call sites in a module, relatively efficiently. The
/// purpose of this pass is to provide optimizations for calls to well-known /// purpose of this pass is to provide optimizations for calls to well-known
/// functions with well-known semantics, such as those in the c library. The /// functions with well-known semantics, such as those in the c library. The
/// class provides the basic infrastructure for handling runOnModule. Whenever /// this pass finds a function call, it asks the appropriate optimizer to /// class provides the basic infrastructure for handling runOnModule. Whenever /// this pass finds a function call, it asks the appropriate optimizer to
/// validate the call (ValidateLibraryCall). If it is validated, then /// validate the call (ValidateLibraryCall). If it is validated, then
/// the OptimizeCall method is also called. /// the OptimizeCall method is also called.
/// @brief A ModulePass for optimizing well-known function calls. /// @brief A ModulePass for optimizing well-known function calls.
class SimplifyLibCalls : public ModulePass class SimplifyLibCalls : public ModulePass
{ {
public: public:
/// We need some target data for accurate signature details that are /// We need some target data for accurate signature details that are
@ -157,8 +157,8 @@ public:
// The call optimizations can be recursive. That is, the optimization might // The call optimizations can be recursive. That is, the optimization might
// generate a call to another function which can also be optimized. This way // generate a call to another function which can also be optimized. This way
// we make the LibCallOptimization instances very specific to the case they // we make the LibCallOptimization instances very specific to the case they
// handle. It also means we need to keep running over the function calls in // handle. It also means we need to keep running over the function calls in
// the module until we don't get any more optimizations possible. // the module until we don't get any more optimizations possible.
bool found_optimization = false; bool found_optimization = false;
do do
@ -167,8 +167,8 @@ public:
for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI) for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI)
{ {
// All the "well-known" functions are external and have external linkage // All the "well-known" functions are external and have external linkage
// because they live in a runtime library somewhere and were (probably) // because they live in a runtime library somewhere and were (probably)
// not compiled by LLVM. So, we only act on external functions that // not compiled by LLVM. So, we only act on external functions that
// have external linkage and non-empty uses. // have external linkage and non-empty uses.
if (!FI->isExternal() || !FI->hasExternalLinkage() || FI->use_empty()) if (!FI->isExternal() || !FI->hasExternalLinkage() || FI->use_empty())
continue; continue;
@ -183,7 +183,7 @@ public:
continue; continue;
// Loop over each of the uses of the function // Loop over each of the uses of the function
for (Value::use_iterator UI = FI->use_begin(), UE = FI->use_end(); for (Value::use_iterator UI = FI->use_begin(), UE = FI->use_end();
UI != UE ; ) UI != UE ; )
{ {
// If the use of the function is a call instruction // If the use of the function is a call instruction
@ -222,7 +222,7 @@ public:
std::vector<const Type*> args; std::vector<const Type*> args;
args.push_back(Type::IntTy); args.push_back(Type::IntTy);
args.push_back(FILEptr_type); args.push_back(FILEptr_type);
FunctionType* fputc_type = FunctionType* fputc_type =
FunctionType::get(Type::IntTy, args, false); FunctionType::get(Type::IntTy, args, false);
fputc_func = M->getOrInsertFunction("fputc",fputc_type); fputc_func = M->getOrInsertFunction("fputc",fputc_type);
} }
@ -239,7 +239,7 @@ public:
args.push_back(TD->getIntPtrType()); args.push_back(TD->getIntPtrType());
args.push_back(TD->getIntPtrType()); args.push_back(TD->getIntPtrType());
args.push_back(FILEptr_type); args.push_back(FILEptr_type);
FunctionType* fwrite_type = FunctionType* fwrite_type =
FunctionType::get(TD->getIntPtrType(), args, false); FunctionType::get(TD->getIntPtrType(), args, false);
fwrite_func = M->getOrInsertFunction("fwrite",fwrite_type); fwrite_func = M->getOrInsertFunction("fwrite",fwrite_type);
} }
@ -253,7 +253,7 @@ public:
{ {
std::vector<const Type*> args; std::vector<const Type*> args;
args.push_back(Type::DoubleTy); args.push_back(Type::DoubleTy);
FunctionType* sqrt_type = FunctionType* sqrt_type =
FunctionType::get(Type::DoubleTy, args, false); FunctionType::get(Type::DoubleTy, args, false);
sqrt_func = M->getOrInsertFunction("sqrt",sqrt_type); sqrt_func = M->getOrInsertFunction("sqrt",sqrt_type);
} }
@ -268,7 +268,7 @@ public:
std::vector<const Type*> args; std::vector<const Type*> args;
args.push_back(PointerType::get(Type::SByteTy)); args.push_back(PointerType::get(Type::SByteTy));
args.push_back(PointerType::get(Type::SByteTy)); args.push_back(PointerType::get(Type::SByteTy));
FunctionType* strcpy_type = FunctionType* strcpy_type =
FunctionType::get(PointerType::get(Type::SByteTy), args, false); FunctionType::get(PointerType::get(Type::SByteTy), args, false);
strcpy_func = M->getOrInsertFunction("strcpy",strcpy_type); strcpy_func = M->getOrInsertFunction("strcpy",strcpy_type);
} }
@ -282,7 +282,7 @@ public:
{ {
std::vector<const Type*> args; std::vector<const Type*> args;
args.push_back(PointerType::get(Type::SByteTy)); args.push_back(PointerType::get(Type::SByteTy));
FunctionType* strlen_type = FunctionType* strlen_type =
FunctionType::get(TD->getIntPtrType(), args, false); FunctionType::get(TD->getIntPtrType(), args, false);
strlen_func = M->getOrInsertFunction("strlen",strlen_type); strlen_func = M->getOrInsertFunction("strlen",strlen_type);
} }
@ -350,21 +350,21 @@ private:
}; };
// Register the pass // Register the pass
RegisterOpt<SimplifyLibCalls> RegisterOpt<SimplifyLibCalls>
X("simplify-libcalls","Simplify well-known library calls"); X("simplify-libcalls","Simplify well-known library calls");
} // anonymous namespace } // anonymous namespace
// The only public symbol in this file which just instantiates the pass object // The only public symbol in this file which just instantiates the pass object
ModulePass *llvm::createSimplifyLibCallsPass() ModulePass *llvm::createSimplifyLibCallsPass()
{ {
return new SimplifyLibCalls(); return new SimplifyLibCalls();
} }
// Classes below here, in the anonymous namespace, are all subclasses of the // Classes below here, in the anonymous namespace, are all subclasses of the
// LibCallOptimization class, each implementing all optimizations possible for a // LibCallOptimization class, each implementing all optimizations possible for a
// single well-known library call. Each has a static singleton instance that // single well-known library call. Each has a static singleton instance that
// auto registers it into the "optlist" global above. // auto registers it into the "optlist" global above.
namespace { namespace {
// Forward declare utility functions. // Forward declare utility functions.
@ -383,7 +383,7 @@ struct ExitInMainOptimization : public LibCallOptimization
virtual ~ExitInMainOptimization() {} virtual ~ExitInMainOptimization() {}
// Make sure the called function looks like exit (int argument, int return // Make sure the called function looks like exit (int argument, int return
// type, external linkage, not varargs). // type, external linkage, not varargs).
virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC) virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC)
{ {
if (f->arg_size() >= 1) if (f->arg_size() >= 1)
@ -396,18 +396,18 @@ struct ExitInMainOptimization : public LibCallOptimization
{ {
// To be careful, we check that the call to exit is coming from "main", that // To be careful, we check that the call to exit is coming from "main", that
// main has external linkage, and the return type of main and the argument // main has external linkage, and the return type of main and the argument
// to exit have the same type. // to exit have the same type.
Function *from = ci->getParent()->getParent(); Function *from = ci->getParent()->getParent();
if (from->hasExternalLinkage()) if (from->hasExternalLinkage())
if (from->getReturnType() == ci->getOperand(1)->getType()) if (from->getReturnType() == ci->getOperand(1)->getType())
if (from->getName() == "main") if (from->getName() == "main")
{ {
// Okay, time to actually do the optimization. First, get the basic // Okay, time to actually do the optimization. First, get the basic
// block of the call instruction // block of the call instruction
BasicBlock* bb = ci->getParent(); BasicBlock* bb = ci->getParent();
// Create a return instruction that we'll replace the call with. // Create a return instruction that we'll replace the call with.
// Note that the argument of the return is the argument of the call // Note that the argument of the return is the argument of the call
// instruction. // instruction.
ReturnInst* ri = new ReturnInst(ci->getOperand(1), ci); ReturnInst* ri = new ReturnInst(ci->getOperand(1), ci);
@ -433,10 +433,10 @@ struct ExitInMainOptimization : public LibCallOptimization
} }
} ExitInMainOptimizer; } ExitInMainOptimizer;
/// This LibCallOptimization will simplify a call to the strcat library /// This LibCallOptimization will simplify a call to the strcat library
/// function. The simplification is possible only if the string being /// function. The simplification is possible only if the string being
/// concatenated is a constant array or a constant expression that results in /// concatenated is a constant array or a constant expression that results in
/// a constant string. In this case we can replace it with strlen + llvm.memcpy /// a constant string. In this case we can replace it with strlen + llvm.memcpy
/// of the constant string. Both of these calls are further reduced, if possible /// of the constant string. Both of these calls are further reduced, if possible
/// on subsequent passes. /// on subsequent passes.
/// @brief Simplify the strcat library function. /// @brief Simplify the strcat library function.
@ -452,10 +452,10 @@ public:
virtual ~StrCatOptimization() {} virtual ~StrCatOptimization() {}
/// @brief Make sure that the "strcat" function has the right prototype /// @brief Make sure that the "strcat" function has the right prototype
virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC) virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC)
{ {
if (f->getReturnType() == PointerType::get(Type::SByteTy)) if (f->getReturnType() == PointerType::get(Type::SByteTy))
if (f->arg_size() == 2) if (f->arg_size() == 2)
{ {
Function::const_arg_iterator AI = f->arg_begin(); Function::const_arg_iterator AI = f->arg_begin();
if (AI++->getType() == PointerType::get(Type::SByteTy)) if (AI++->getType() == PointerType::get(Type::SByteTy))
@ -476,7 +476,7 @@ public:
Value* dest = ci->getOperand(1); Value* dest = ci->getOperand(1);
Value* src = ci->getOperand(2); Value* src = ci->getOperand(2);
// Extract the initializer (while making numerous checks) from the // Extract the initializer (while making numerous checks) from the
// source operand of the call to strcat. If we get null back, one of // source operand of the call to strcat. If we get null back, one of
// a variety of checks in get_GVInitializer failed // a variety of checks in get_GVInitializer failed
uint64_t len = 0; uint64_t len = 0;
@ -495,19 +495,19 @@ public:
// terminator as well. // terminator as well.
len++; len++;
// We need to find the end of the destination string. That's where the // We need to find the end of the destination string. That's where the
// memory is to be moved to. We just generate a call to strlen (further // memory is to be moved to. We just generate a call to strlen (further
// optimized in another pass). Note that the SLC.get_strlen() call // optimized in another pass). Note that the SLC.get_strlen() call
// caches the Function* for us. // caches the Function* for us.
CallInst* strlen_inst = CallInst* strlen_inst =
new CallInst(SLC.get_strlen(), dest, dest->getName()+".len",ci); new CallInst(SLC.get_strlen(), dest, dest->getName()+".len",ci);
// Now that we have the destination's length, we must index into the // Now that we have the destination's length, we must index into the
// destination's pointer to get the actual memcpy destination (end of // destination's pointer to get the actual memcpy destination (end of
// the string .. we're concatenating). // the string .. we're concatenating).
std::vector<Value*> idx; std::vector<Value*> idx;
idx.push_back(strlen_inst); idx.push_back(strlen_inst);
GetElementPtrInst* gep = GetElementPtrInst* gep =
new GetElementPtrInst(dest,idx,dest->getName()+".indexed",ci); new GetElementPtrInst(dest,idx,dest->getName()+".indexed",ci);
// We have enough information to now generate the memcpy call to // We have enough information to now generate the memcpy call to
@ -519,8 +519,8 @@ public:
vals.push_back(ConstantUInt::get(Type::UIntTy,1)); // alignment vals.push_back(ConstantUInt::get(Type::UIntTy,1)); // alignment
new CallInst(SLC.get_memcpy(), vals, "", ci); new CallInst(SLC.get_memcpy(), vals, "", ci);
// Finally, substitute the first operand of the strcat call for the // Finally, substitute the first operand of the strcat call for the
// strcat call itself since strcat returns its first operand; and, // strcat call itself since strcat returns its first operand; and,
// kill the strcat CallInst. // kill the strcat CallInst.
ci->replaceAllUsesWith(dest); ci->replaceAllUsesWith(dest);
ci->eraseFromParent(); ci->eraseFromParent();
@ -528,7 +528,7 @@ public:
} }
} StrCatOptimizer; } StrCatOptimizer;
/// This LibCallOptimization will simplify a call to the strchr library /// This LibCallOptimization will simplify a call to the strchr library
/// function. It optimizes out cases where the arguments are both constant /// function. It optimizes out cases where the arguments are both constant
/// and the result can be determined statically. /// and the result can be determined statically.
/// @brief Simplify the strcmp library function. /// @brief Simplify the strcmp library function.
@ -540,9 +540,9 @@ public:
virtual ~StrChrOptimization() {} virtual ~StrChrOptimization() {}
/// @brief Make sure that the "strchr" function has the right prototype /// @brief Make sure that the "strchr" function has the right prototype
virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC) virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC)
{ {
if (f->getReturnType() == PointerType::get(Type::SByteTy) && if (f->getReturnType() == PointerType::get(Type::SByteTy) &&
f->arg_size() == 2) f->arg_size() == 2)
return true; return true;
return false; return false;
@ -620,7 +620,7 @@ public:
} }
} StrChrOptimizer; } StrChrOptimizer;
/// This LibCallOptimization will simplify a call to the strcmp library /// This LibCallOptimization will simplify a call to the strcmp library
/// function. It optimizes out cases where one or both arguments are constant /// function. It optimizes out cases where one or both arguments are constant
/// and the result can be determined statically. /// and the result can be determined statically.
/// @brief Simplify the strcmp library function. /// @brief Simplify the strcmp library function.
@ -632,7 +632,7 @@ public:
virtual ~StrCmpOptimization() {} virtual ~StrCmpOptimization() {}
/// @brief Make sure that the "strcmp" function has the right prototype /// @brief Make sure that the "strcmp" function has the right prototype
virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC) virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC)
{ {
if (f->getReturnType() == Type::IntTy && f->arg_size() == 2) if (f->getReturnType() == Type::IntTy && f->arg_size() == 2)
return true; return true;
@ -644,7 +644,7 @@ public:
{ {
// First, check to see if src and destination are the same. If they are, // First, check to see if src and destination are the same. If they are,
// then the optimization is to replace the CallInst with a constant 0 // then the optimization is to replace the CallInst with a constant 0
// because the call is a no-op. // because the call is a no-op.
Value* s1 = ci->getOperand(1); Value* s1 = ci->getOperand(1);
Value* s2 = ci->getOperand(2); Value* s2 = ci->getOperand(2);
if (s1 == s2) if (s1 == s2)
@ -664,9 +664,9 @@ public:
if (len_1 == 0) if (len_1 == 0)
{ {
// strcmp("",x) -> *x // strcmp("",x) -> *x
LoadInst* load = LoadInst* load =
new LoadInst(CastToCStr(s2,*ci), ci->getName()+".load",ci); new LoadInst(CastToCStr(s2,*ci), ci->getName()+".load",ci);
CastInst* cast = CastInst* cast =
new CastInst(load,Type::IntTy,ci->getName()+".int",ci); new CastInst(load,Type::IntTy,ci->getName()+".int",ci);
ci->replaceAllUsesWith(cast); ci->replaceAllUsesWith(cast);
ci->eraseFromParent(); ci->eraseFromParent();
@ -683,9 +683,9 @@ public:
if (len_2 == 0) if (len_2 == 0)
{ {
// strcmp(x,"") -> *x // strcmp(x,"") -> *x
LoadInst* load = LoadInst* load =
new LoadInst(CastToCStr(s1,*ci),ci->getName()+".val",ci); new LoadInst(CastToCStr(s1,*ci),ci->getName()+".val",ci);
CastInst* cast = CastInst* cast =
new CastInst(load,Type::IntTy,ci->getName()+".int",ci); new CastInst(load,Type::IntTy,ci->getName()+".int",ci);
ci->replaceAllUsesWith(cast); ci->replaceAllUsesWith(cast);
ci->eraseFromParent(); ci->eraseFromParent();
@ -707,7 +707,7 @@ public:
} }
} StrCmpOptimizer; } StrCmpOptimizer;
/// This LibCallOptimization will simplify a call to the strncmp library /// This LibCallOptimization will simplify a call to the strncmp library
/// function. It optimizes out cases where one or both arguments are constant /// function. It optimizes out cases where one or both arguments are constant
/// and the result can be determined statically. /// and the result can be determined statically.
/// @brief Simplify the strncmp library function. /// @brief Simplify the strncmp library function.
@ -719,7 +719,7 @@ public:
virtual ~StrNCmpOptimization() {} virtual ~StrNCmpOptimization() {}
/// @brief Make sure that the "strncmp" function has the right prototype /// @brief Make sure that the "strncmp" function has the right prototype
virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC) virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC)
{ {
if (f->getReturnType() == Type::IntTy && f->arg_size() == 3) if (f->getReturnType() == Type::IntTy && f->arg_size() == 3)
return true; return true;
@ -731,7 +731,7 @@ public:
{ {
// First, check to see if src and destination are the same. If they are, // First, check to see if src and destination are the same. If they are,
// then the optimization is to replace the CallInst with a constant 0 // then the optimization is to replace the CallInst with a constant 0
// because the call is a no-op. // because the call is a no-op.
Value* s1 = ci->getOperand(1); Value* s1 = ci->getOperand(1);
Value* s2 = ci->getOperand(2); Value* s2 = ci->getOperand(2);
if (s1 == s2) if (s1 == s2)
@ -756,7 +756,7 @@ public:
ci->replaceAllUsesWith(ConstantInt::get(Type::IntTy,0)); ci->replaceAllUsesWith(ConstantInt::get(Type::IntTy,0));
ci->eraseFromParent(); ci->eraseFromParent();
return true; return true;
} }
} }
bool isstr_1 = false; bool isstr_1 = false;
@ -769,7 +769,7 @@ public:
{ {
// strncmp("",x) -> *x // strncmp("",x) -> *x
LoadInst* load = new LoadInst(s1,ci->getName()+".load",ci); LoadInst* load = new LoadInst(s1,ci->getName()+".load",ci);
CastInst* cast = CastInst* cast =
new CastInst(load,Type::IntTy,ci->getName()+".int",ci); new CastInst(load,Type::IntTy,ci->getName()+".int",ci);
ci->replaceAllUsesWith(cast); ci->replaceAllUsesWith(cast);
ci->eraseFromParent(); ci->eraseFromParent();
@ -787,7 +787,7 @@ public:
{ {
// strncmp(x,"") -> *x // strncmp(x,"") -> *x
LoadInst* load = new LoadInst(s2,ci->getName()+".val",ci); LoadInst* load = new LoadInst(s2,ci->getName()+".val",ci);
CastInst* cast = CastInst* cast =
new CastInst(load,Type::IntTy,ci->getName()+".int",ci); new CastInst(load,Type::IntTy,ci->getName()+".int",ci);
ci->replaceAllUsesWith(cast); ci->replaceAllUsesWith(cast);
ci->eraseFromParent(); ci->eraseFromParent();
@ -809,8 +809,8 @@ public:
} }
} StrNCmpOptimizer; } StrNCmpOptimizer;
/// This LibCallOptimization will simplify a call to the strcpy library /// This LibCallOptimization will simplify a call to the strcpy library
/// function. Two optimizations are possible: /// function. Two optimizations are possible:
/// (1) If src and dest are the same and not volatile, just return dest /// (1) If src and dest are the same and not volatile, just return dest
/// (2) If the src is a constant then we can convert to llvm.memmove /// (2) If the src is a constant then we can convert to llvm.memmove
/// @brief Simplify the strcpy library function. /// @brief Simplify the strcpy library function.
@ -822,10 +822,10 @@ public:
virtual ~StrCpyOptimization() {} virtual ~StrCpyOptimization() {}
/// @brief Make sure that the "strcpy" function has the right prototype /// @brief Make sure that the "strcpy" function has the right prototype
virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC) virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC)
{ {
if (f->getReturnType() == PointerType::get(Type::SByteTy)) if (f->getReturnType() == PointerType::get(Type::SByteTy))
if (f->arg_size() == 2) if (f->arg_size() == 2)
{ {
Function::const_arg_iterator AI = f->arg_begin(); Function::const_arg_iterator AI = f->arg_begin();
if (AI++->getType() == PointerType::get(Type::SByteTy)) if (AI++->getType() == PointerType::get(Type::SByteTy))
@ -843,7 +843,7 @@ public:
{ {
// First, check to see if src and destination are the same. If they are, // First, check to see if src and destination are the same. If they are,
// then the optimization is to replace the CallInst with the destination // then the optimization is to replace the CallInst with the destination
// because the call is a no-op. Note that this corresponds to the // because the call is a no-op. Note that this corresponds to the
// degenerate strcpy(X,X) case which should have "undefined" results // degenerate strcpy(X,X) case which should have "undefined" results
// according to the C specification. However, it occurs sometimes and // according to the C specification. However, it occurs sometimes and
// we optimize it as a no-op. // we optimize it as a no-op.
@ -855,7 +855,7 @@ public:
ci->eraseFromParent(); ci->eraseFromParent();
return true; return true;
} }
// Get the length of the constant string referenced by the second operand, // Get the length of the constant string referenced by the second operand,
// the "src" parameter. Fail the optimization if we can't get the length // the "src" parameter. Fail the optimization if we can't get the length
// (note that getConstantStringLength does lots of checks to make sure this // (note that getConstantStringLength does lots of checks to make sure this
@ -890,8 +890,8 @@ public:
vals.push_back(ConstantUInt::get(Type::UIntTy,1)); // alignment vals.push_back(ConstantUInt::get(Type::UIntTy,1)); // alignment
new CallInst(SLC.get_memcpy(), vals, "", ci); new CallInst(SLC.get_memcpy(), vals, "", ci);
// Finally, substitute the first operand of the strcat call for the // Finally, substitute the first operand of the strcat call for the
// strcat call itself since strcat returns its first operand; and, // strcat call itself since strcat returns its first operand; and,
// kill the strcat CallInst. // kill the strcat CallInst.
ci->replaceAllUsesWith(dest); ci->replaceAllUsesWith(dest);
ci->eraseFromParent(); ci->eraseFromParent();
@ -899,8 +899,8 @@ public:
} }
} StrCpyOptimizer; } StrCpyOptimizer;
/// This LibCallOptimization will simplify a call to the strlen library /// This LibCallOptimization will simplify a call to the strlen library
/// function by replacing it with a constant value if the string provided to /// function by replacing it with a constant value if the string provided to
/// it is a constant array. /// it is a constant array.
/// @brief Simplify the strlen library function. /// @brief Simplify the strlen library function.
struct StrLenOptimization : public LibCallOptimization struct StrLenOptimization : public LibCallOptimization
@ -913,7 +913,7 @@ struct StrLenOptimization : public LibCallOptimization
virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC) virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC)
{ {
if (f->getReturnType() == SLC.getTargetData()->getIntPtrType()) if (f->getReturnType() == SLC.getTargetData()->getIntPtrType())
if (f->arg_size() == 1) if (f->arg_size() == 1)
if (Function::const_arg_iterator AI = f->arg_begin()) if (Function::const_arg_iterator AI = f->arg_begin())
if (AI->getType() == PointerType::get(Type::SByteTy)) if (AI->getType() == PointerType::get(Type::SByteTy))
return true; return true;
@ -929,7 +929,7 @@ struct StrLenOptimization : public LibCallOptimization
return false; return false;
// Does the call to strlen have exactly one use? // Does the call to strlen have exactly one use?
if (ci->hasOneUse()) if (ci->hasOneUse())
// Is that single use a binary operator? // Is that single use a binary operator?
if (BinaryOperator* bop = dyn_cast<BinaryOperator>(ci->use_back())) if (BinaryOperator* bop = dyn_cast<BinaryOperator>(ci->use_back()))
// Is it compared against a constant integer? // Is it compared against a constant integer?
@ -969,8 +969,8 @@ struct StrLenOptimization : public LibCallOptimization
} }
} StrLenOptimizer; } StrLenOptimizer;
/// This LibCallOptimization will simplify a call to the memcpy library /// This LibCallOptimization will simplify a call to the memcpy library
/// function by expanding it out to a single store of size 0, 1, 2, 4, or 8 /// function by expanding it out to a single store of size 0, 1, 2, 4, or 8
/// bytes depending on the length of the string and the alignment. Additional /// bytes depending on the length of the string and the alignment. Additional
/// optimizations are possible in code generation (sequence of immediate store) /// optimizations are possible in code generation (sequence of immediate store)
/// @brief Simplify the memcpy library function. /// @brief Simplify the memcpy library function.
@ -981,7 +981,7 @@ struct LLVMMemCpyOptimization : public LibCallOptimization
"Number of 'llvm.memcpy' calls simplified") {} "Number of 'llvm.memcpy' calls simplified") {}
protected: protected:
/// @brief Subclass Constructor /// @brief Subclass Constructor
LLVMMemCpyOptimization(const char* fname, const char* desc) LLVMMemCpyOptimization(const char* fname, const char* desc)
: LibCallOptimization(fname, desc) {} : LibCallOptimization(fname, desc) {}
public: public:
@ -1038,9 +1038,9 @@ public:
} }
// Cast source and dest to the right sized primitive and then load/store // Cast source and dest to the right sized primitive and then load/store
CastInst* SrcCast = CastInst* SrcCast =
new CastInst(src,PointerType::get(castType),src->getName()+".cast",ci); new CastInst(src,PointerType::get(castType),src->getName()+".cast",ci);
CastInst* DestCast = CastInst* DestCast =
new CastInst(dest,PointerType::get(castType),dest->getName()+".cast",ci); new CastInst(dest,PointerType::get(castType),dest->getName()+".cast",ci);
LoadInst* LI = new LoadInst(SrcCast,SrcCast->getName()+".val",ci); LoadInst* LI = new LoadInst(SrcCast,SrcCast->getName()+".val",ci);
StoreInst* SI = new StoreInst(LI, DestCast, ci); StoreInst* SI = new StoreInst(LI, DestCast, ci);
@ -1049,8 +1049,8 @@ public:
} }
} LLVMMemCpyOptimizer; } LLVMMemCpyOptimizer;
/// This LibCallOptimization will simplify a call to the memmove library /// This LibCallOptimization will simplify a call to the memmove library
/// function. It is identical to MemCopyOptimization except for the name of /// function. It is identical to MemCopyOptimization except for the name of
/// the intrinsic. /// the intrinsic.
/// @brief Simplify the memmove library function. /// @brief Simplify the memmove library function.
struct LLVMMemMoveOptimization : public LLVMMemCpyOptimization struct LLVMMemMoveOptimization : public LLVMMemCpyOptimization
@ -1061,9 +1061,9 @@ struct LLVMMemMoveOptimization : public LLVMMemCpyOptimization
} LLVMMemMoveOptimizer; } LLVMMemMoveOptimizer;
/// This LibCallOptimization will simplify a call to the memset library /// This LibCallOptimization will simplify a call to the memset library
/// function by expanding it out to a single store of size 0, 1, 2, 4, or 8 /// function by expanding it out to a single store of size 0, 1, 2, 4, or 8
/// bytes depending on the length argument. /// bytes depending on the length argument.
struct LLVMMemSetOptimization : public LibCallOptimization struct LLVMMemSetOptimization : public LibCallOptimization
{ {
/// @brief Default Constructor /// @brief Default Constructor
@ -1084,7 +1084,7 @@ public:
/// Because of alignment and instruction information that we don't have, we /// Because of alignment and instruction information that we don't have, we
/// leave the bulk of this to the code generators. The optimization here just /// leave the bulk of this to the code generators. The optimization here just
/// deals with a few degenerate cases where the length parameter is constant /// deals with a few degenerate cases where the length parameter is constant
/// and the alignment matches the sizes of our intrinsic types so we can do /// and the alignment matches the sizes of our intrinsic types so we can do
/// store instead of the memcpy call. Other calls are transformed into the /// store instead of the memcpy call. Other calls are transformed into the
/// llvm.memset intrinsic. /// llvm.memset intrinsic.
/// @brief Perform the memset optimization. /// @brief Perform the memset optimization.
@ -1127,7 +1127,7 @@ public:
return false; return false;
// memset(s,c,n) -> store s, c (for n=1,2,4,8) // memset(s,c,n) -> store s, c (for n=1,2,4,8)
// Extract the fill character // Extract the fill character
uint64_t fill_char = FILL->getValue(); uint64_t fill_char = FILL->getValue();
uint64_t fill_value = fill_char; uint64_t fill_value = fill_char;
@ -1138,18 +1138,18 @@ public:
Type* castType = 0; Type* castType = 0;
switch (len) switch (len)
{ {
case 1: case 1:
castType = Type::UByteTy; castType = Type::UByteTy;
break; break;
case 2: case 2:
castType = Type::UShortTy; castType = Type::UShortTy;
fill_value |= fill_char << 8; fill_value |= fill_char << 8;
break; break;
case 4: case 4:
castType = Type::UIntTy; castType = Type::UIntTy;
fill_value |= fill_char << 8 | fill_char << 16 | fill_char << 24; fill_value |= fill_char << 8 | fill_char << 16 | fill_char << 24;
break; break;
case 8: case 8:
castType = Type::ULongTy; castType = Type::ULongTy;
fill_value |= fill_char << 8 | fill_char << 16 | fill_char << 24; fill_value |= fill_char << 8 | fill_char << 16 | fill_char << 24;
fill_value |= fill_char << 32 | fill_char << 40 | fill_char << 48; fill_value |= fill_char << 32 | fill_char << 40 | fill_char << 48;
@ -1160,7 +1160,7 @@ public:
} }
// Cast dest to the right sized primitive and then load/store // Cast dest to the right sized primitive and then load/store
CastInst* DestCast = CastInst* DestCast =
new CastInst(dest,PointerType::get(castType),dest->getName()+".cast",ci); new CastInst(dest,PointerType::get(castType),dest->getName()+".cast",ci);
new StoreInst(ConstantUInt::get(castType,fill_value),DestCast, ci); new StoreInst(ConstantUInt::get(castType,fill_value),DestCast, ci);
ci->eraseFromParent(); ci->eraseFromParent();
@ -1168,8 +1168,8 @@ public:
} }
} LLVMMemSetOptimizer; } LLVMMemSetOptimizer;
/// This LibCallOptimization will simplify calls to the "pow" library /// This LibCallOptimization will simplify calls to the "pow" library
/// function. It looks for cases where the result of pow is well known and /// function. It looks for cases where the result of pow is well known and
/// substitutes the appropriate value. /// substitutes the appropriate value.
/// @brief Simplify the pow library function. /// @brief Simplify the pow library function.
struct PowOptimization : public LibCallOptimization struct PowOptimization : public LibCallOptimization
@ -1204,8 +1204,8 @@ public:
ci->eraseFromParent(); ci->eraseFromParent();
return true; return true;
} }
} }
else if (ConstantFP* Op2 = dyn_cast<ConstantFP>(expn)) else if (ConstantFP* Op2 = dyn_cast<ConstantFP>(expn))
{ {
double Op2V = Op2->getValue(); double Op2V = Op2->getValue();
if (Op2V == 0.0) if (Op2V == 0.0)
@ -1245,7 +1245,7 @@ public:
} }
} PowOptimizer; } PowOptimizer;
/// This LibCallOptimization will simplify calls to the "fprintf" library /// This LibCallOptimization will simplify calls to the "fprintf" library
/// function. It looks for cases where the result of fprintf is not used and the /// function. It looks for cases where the result of fprintf is not used and the
/// operation can be reduced to something simpler. /// operation can be reduced to something simpler.
/// @brief Simplify the pow library function. /// @brief Simplify the pow library function.
@ -1273,14 +1273,14 @@ public:
if (ci->getNumOperands() > 4 || ci->getNumOperands() <= 2) if (ci->getNumOperands() > 4 || ci->getNumOperands() <= 2)
return false; return false;
// If the result of the fprintf call is used, none of these optimizations // If the result of the fprintf call is used, none of these optimizations
// can be made. // can be made.
if (!ci->hasNUses(0)) if (!ci->hasNUses(0))
return false; return false;
// All the optimizations depend on the length of the second argument and the // All the optimizations depend on the length of the second argument and the
// fact that it is a constant string array. Check that now // fact that it is a constant string array. Check that now
uint64_t len = 0; uint64_t len = 0;
ConstantArray* CA = 0; ConstantArray* CA = 0;
if (!getConstantStringLength(ci->getOperand(2), len, &CA)) if (!getConstantStringLength(ci->getOperand(2), len, &CA))
return false; return false;
@ -1296,11 +1296,11 @@ public:
if (CI->getRawValue() == '%') if (CI->getRawValue() == '%')
return false; // we found end of string return false; // we found end of string
} }
else else
return false; return false;
} }
// fprintf(file,fmt) -> fwrite(fmt,strlen(fmt),file) // fprintf(file,fmt) -> fwrite(fmt,strlen(fmt),file)
const Type* FILEptr_type = ci->getOperand(1)->getType(); const Type* FILEptr_type = ci->getOperand(1)->getType();
Function* fwrite_func = SLC.get_fwrite(FILEptr_type); Function* fwrite_func = SLC.get_fwrite(FILEptr_type);
if (!fwrite_func) if (!fwrite_func)
@ -1339,12 +1339,12 @@ public:
{ {
case 's': case 's':
{ {
uint64_t len = 0; uint64_t len = 0;
ConstantArray* CA = 0; ConstantArray* CA = 0;
if (!getConstantStringLength(ci->getOperand(3), len, &CA)) if (!getConstantStringLength(ci->getOperand(3), len, &CA))
return false; return false;
// fprintf(file,"%s",str) -> fwrite(fmt,strlen(fmt),1,file) // fprintf(file,"%s",str) -> fwrite(fmt,strlen(fmt),1,file)
const Type* FILEptr_type = ci->getOperand(1)->getType(); const Type* FILEptr_type = ci->getOperand(1)->getType();
Function* fwrite_func = SLC.get_fwrite(FILEptr_type); Function* fwrite_func = SLC.get_fwrite(FILEptr_type);
if (!fwrite_func) if (!fwrite_func)
@ -1381,7 +1381,7 @@ public:
} }
} FPrintFOptimizer; } FPrintFOptimizer;
/// This LibCallOptimization will simplify calls to the "sprintf" library /// This LibCallOptimization will simplify calls to the "sprintf" library
/// function. It looks for cases where the result of sprintf is not used and the /// function. It looks for cases where the result of sprintf is not used and the
/// operation can be reduced to something simpler. /// operation can be reduced to something simpler.
/// @brief Simplify the pow library function. /// @brief Simplify the pow library function.
@ -1411,7 +1411,7 @@ public:
// All the optimizations depend on the length of the second argument and the // All the optimizations depend on the length of the second argument and the
// fact that it is a constant string array. Check that now // fact that it is a constant string array. Check that now
uint64_t len = 0; uint64_t len = 0;
ConstantArray* CA = 0; ConstantArray* CA = 0;
if (!getConstantStringLength(ci->getOperand(2), len, &CA)) if (!getConstantStringLength(ci->getOperand(2), len, &CA))
return false; return false;
@ -1436,14 +1436,14 @@ public:
if (CI->getRawValue() == '%') if (CI->getRawValue() == '%')
return false; // we found a %, can't optimize return false; // we found a %, can't optimize
} }
else else
return false; // initializer is not constant int, can't optimize return false; // initializer is not constant int, can't optimize
} }
// Increment length because we want to copy the null byte too // Increment length because we want to copy the null byte too
len++; len++;
// sprintf(str,fmt) -> llvm.memcpy(str,fmt,strlen(fmt),1) // sprintf(str,fmt) -> llvm.memcpy(str,fmt,strlen(fmt),1)
Function* memcpy_func = SLC.get_memcpy(); Function* memcpy_func = SLC.get_memcpy();
if (!memcpy_func) if (!memcpy_func)
return false; return false;
@ -1477,7 +1477,7 @@ public:
uint64_t len = 0; uint64_t len = 0;
if (ci->hasNUses(0)) if (ci->hasNUses(0))
{ {
// sprintf(dest,"%s",str) -> strcpy(dest,str) // sprintf(dest,"%s",str) -> strcpy(dest,str)
Function* strcpy_func = SLC.get_strcpy(); Function* strcpy_func = SLC.get_strcpy();
if (!strcpy_func) if (!strcpy_func)
return false; return false;
@ -1506,7 +1506,7 @@ public:
case 'c': case 'c':
{ {
// sprintf(dest,"%c",chr) -> store chr, dest // sprintf(dest,"%c",chr) -> store chr, dest
CastInst* cast = CastInst* cast =
new CastInst(ci->getOperand(3),Type::SByteTy,"char",ci); new CastInst(ci->getOperand(3),Type::SByteTy,"char",ci);
new StoreInst(cast, ci->getOperand(1), ci); new StoreInst(cast, ci->getOperand(1), ci);
GetElementPtrInst* gep = new GetElementPtrInst(ci->getOperand(1), GetElementPtrInst* gep = new GetElementPtrInst(ci->getOperand(1),
@ -1524,7 +1524,7 @@ public:
} }
} SPrintFOptimizer; } SPrintFOptimizer;
/// This LibCallOptimization will simplify calls to the "fputs" library /// This LibCallOptimization will simplify calls to the "fputs" library
/// function. It looks for cases where the result of fputs is not used and the /// function. It looks for cases where the result of fputs is not used and the
/// operation can be reduced to something simpler. /// operation can be reduced to something simpler.
/// @brief Simplify the pow library function. /// @brief Simplify the pow library function.
@ -1549,12 +1549,12 @@ public:
virtual bool OptimizeCall(CallInst* ci, SimplifyLibCalls& SLC) virtual bool OptimizeCall(CallInst* ci, SimplifyLibCalls& SLC)
{ {
// If the result is used, none of these optimizations work // If the result is used, none of these optimizations work
if (!ci->hasNUses(0)) if (!ci->hasNUses(0))
return false; return false;
// All the optimizations depend on the length of the first argument and the // All the optimizations depend on the length of the first argument and the
// fact that it is a constant string array. Check that now // fact that it is a constant string array. Check that now
uint64_t len = 0; uint64_t len = 0;
if (!getConstantStringLength(ci->getOperand(1), len)) if (!getConstantStringLength(ci->getOperand(1), len))
return false; return false;
@ -1578,7 +1578,7 @@ public:
break; break;
} }
default: default:
{ {
// fputs(s,F) -> fwrite(s,1,len,F) (if s is constant and strlen(s) > 1) // fputs(s,F) -> fwrite(s,1,len,F) (if s is constant and strlen(s) > 1)
const Type* FILEptr_type = ci->getOperand(2)->getType(); const Type* FILEptr_type = ci->getOperand(2)->getType();
Function* fwrite_func = SLC.get_fwrite(FILEptr_type); Function* fwrite_func = SLC.get_fwrite(FILEptr_type);
@ -1598,7 +1598,7 @@ public:
} }
} PutsOptimizer; } PutsOptimizer;
/// This LibCallOptimization will simplify calls to the "isdigit" library /// This LibCallOptimization will simplify calls to the "isdigit" library
/// function. It simply does range checks the parameter explicitly. /// function. It simply does range checks the parameter explicitly.
/// @brief Simplify the isdigit library function. /// @brief Simplify the isdigit library function.
struct IsDigitOptimization : public LibCallOptimization struct IsDigitOptimization : public LibCallOptimization
@ -1634,7 +1634,7 @@ public:
} }
// isdigit(c) -> (unsigned)c - '0' <= 9 // isdigit(c) -> (unsigned)c - '0' <= 9
CastInst* cast = CastInst* cast =
new CastInst(ci->getOperand(1),Type::UIntTy, new CastInst(ci->getOperand(1),Type::UIntTy,
ci->getOperand(1)->getName()+".uint",ci); ci->getOperand(1)->getName()+".uint",ci);
BinaryOperator* sub_inst = BinaryOperator::create(Instruction::Sub,cast, BinaryOperator* sub_inst = BinaryOperator::create(Instruction::Sub,cast,
@ -1643,7 +1643,7 @@ public:
SetCondInst* setcond_inst = new SetCondInst(Instruction::SetLE,sub_inst, SetCondInst* setcond_inst = new SetCondInst(Instruction::SetLE,sub_inst,
ConstantUInt::get(Type::UIntTy,9), ConstantUInt::get(Type::UIntTy,9),
ci->getOperand(1)->getName()+".cmp",ci); ci->getOperand(1)->getName()+".cmp",ci);
CastInst* c2 = CastInst* c2 =
new CastInst(setcond_inst,Type::IntTy, new CastInst(setcond_inst,Type::IntTy,
ci->getOperand(1)->getName()+".isdigit",ci); ci->getOperand(1)->getName()+".isdigit",ci);
ci->replaceAllUsesWith(c2); ci->replaceAllUsesWith(c2);
@ -1652,7 +1652,7 @@ public:
} }
} IsDigitOptimizer; } IsDigitOptimizer;
/// This LibCallOptimization will simplify calls to the "toascii" library /// This LibCallOptimization will simplify calls to the "toascii" library
/// function. It simply does the corresponding and operation to restrict the /// function. It simply does the corresponding and operation to restrict the
/// range of values to the ASCII character set (0-127). /// range of values to the ASCII character set (0-127).
/// @brief Simplify the toascii library function. /// @brief Simplify the toascii library function.
@ -1687,7 +1687,7 @@ public:
} ToAsciiOptimizer; } ToAsciiOptimizer;
/// This LibCallOptimization will simplify calls to the "ffs" library /// This LibCallOptimization will simplify calls to the "ffs" library
/// calls which find the first set bit in an int, long, or long long. The /// calls which find the first set bit in an int, long, or long long. The
/// optimization is to compute the result at compile time if the argument is /// optimization is to compute the result at compile time if the argument is
/// a constant. /// a constant.
/// @brief Simplify the ffs library function. /// @brief Simplify the ffs library function.
@ -1742,10 +1742,10 @@ public:
std::vector<const Type*> args; std::vector<const Type*> args;
args.push_back(arg_type); args.push_back(arg_type);
FunctionType* llvm_cttz_type = FunctionType::get(arg_type,args,false); FunctionType* llvm_cttz_type = FunctionType::get(arg_type,args,false);
Function* F = Function* F =
SLC.getModule()->getOrInsertFunction("llvm.cttz",llvm_cttz_type); SLC.getModule()->getOrInsertFunction("llvm.cttz",llvm_cttz_type);
std::string inst_name(ci->getName()+".ffs"); std::string inst_name(ci->getName()+".ffs");
Instruction* call = Instruction* call =
new CallInst(F, ci->getOperand(1), inst_name, ci); new CallInst(F, ci->getOperand(1), inst_name, ci);
if (arg_type != Type::IntTy) if (arg_type != Type::IntTy)
call = new CastInst(call, Type::IntTy, inst_name, ci); call = new CastInst(call, Type::IntTy, inst_name, ci);
@ -1788,10 +1788,10 @@ public:
} FFSLLOptimizer; } FFSLLOptimizer;
/// A function to compute the length of a null-terminated constant array of /// A function to compute the length of a null-terminated constant array of
/// integers. This function can't rely on the size of the constant array /// integers. This function can't rely on the size of the constant array
/// because there could be a null terminator in the middle of the array. /// because there could be a null terminator in the middle of the array.
/// We also have to bail out if we find a non-integer constant initializer /// We also have to bail out if we find a non-integer constant initializer
/// of one of the elements or if there is no null-terminator. The logic /// of one of the elements or if there is no null-terminator. The logic
/// below checks each of these conditions and will return true only if all /// below checks each of these conditions and will return true only if all
/// conditions are met. In that case, the \p len parameter is set to the length /// conditions are met. In that case, the \p len parameter is set to the length
/// of the null-terminated string. If false is returned, the conditions were /// of the null-terminated string. If false is returned, the conditions were
@ -1800,10 +1800,10 @@ public:
bool getConstantStringLength(Value* V, uint64_t& len, ConstantArray** CA ) bool getConstantStringLength(Value* V, uint64_t& len, ConstantArray** CA )
{ {
assert(V != 0 && "Invalid args to getConstantStringLength"); assert(V != 0 && "Invalid args to getConstantStringLength");
len = 0; // make sure we initialize this len = 0; // make sure we initialize this
User* GEP = 0; User* GEP = 0;
// If the value is not a GEP instruction nor a constant expression with a // If the value is not a GEP instruction nor a constant expression with a
// GEP instruction, then return false because ConstantArray can't occur // GEP instruction, then return false because ConstantArray can't occur
// any other way // any other way
if (GetElementPtrInst* GEPI = dyn_cast<GetElementPtrInst>(V)) if (GetElementPtrInst* GEPI = dyn_cast<GetElementPtrInst>(V))
GEP = GEPI; GEP = GEPI;
@ -1820,7 +1820,7 @@ bool getConstantStringLength(Value* V, uint64_t& len, ConstantArray** CA )
return false; return false;
// Check to make sure that the first operand of the GEP is an integer and // Check to make sure that the first operand of the GEP is an integer and
// has value 0 so that we are sure we're indexing into the initializer. // has value 0 so that we are sure we're indexing into the initializer.
if (ConstantInt* op1 = dyn_cast<ConstantInt>(GEP->getOperand(1))) if (ConstantInt* op1 = dyn_cast<ConstantInt>(GEP->getOperand(1)))
{ {
if (!op1->isNullValue()) if (!op1->isNullValue())
@ -1830,7 +1830,7 @@ bool getConstantStringLength(Value* V, uint64_t& len, ConstantArray** CA )
return false; return false;
// Ensure that the second operand is a ConstantInt. If it isn't then this // Ensure that the second operand is a ConstantInt. If it isn't then this
// GEP is wonky and we're not really sure what were referencing into and // GEP is wonky and we're not really sure what were referencing into and
// better of not optimizing it. While we're at it, get the second index // better of not optimizing it. While we're at it, get the second index
// value. We'll need this later for indexing the ConstantArray. // value. We'll need this later for indexing the ConstantArray.
uint64_t start_idx = 0; uint64_t start_idx = 0;
@ -1867,7 +1867,7 @@ bool getConstantStringLength(Value* V, uint64_t& len, ConstantArray** CA )
uint64_t max_elems = A->getType()->getNumElements(); uint64_t max_elems = A->getType()->getNumElements();
// Traverse the constant array from start_idx (derived above) which is // Traverse the constant array from start_idx (derived above) which is
// the place the GEP refers to in the array. // the place the GEP refers to in the array.
for ( len = start_idx; len < max_elems; len++) for ( len = start_idx; len < max_elems; len++)
{ {
if (ConstantInt* CI = dyn_cast<ConstantInt>(A->getOperand(len))) if (ConstantInt* CI = dyn_cast<ConstantInt>(A->getOperand(len)))
@ -1899,7 +1899,7 @@ Value *CastToCStr(Value *V, Instruction &IP) {
return V; return V;
} }
// TODO: // TODO:
// Additional cases that we need to add to this file: // Additional cases that we need to add to this file:
// //
// cbrt: // cbrt:
@ -1915,7 +1915,7 @@ Value *CastToCStr(Value *V, Instruction &IP) {
// //
// isascii: // isascii:
// * isascii(c) -> ((c & ~0x7f) == 0) // * isascii(c) -> ((c & ~0x7f) == 0)
// //
// isdigit: // isdigit:
// * isdigit(c) -> (unsigned)(c) - '0' <= 9 // * isdigit(c) -> (unsigned)(c) - '0' <= 9
// //
@ -1939,7 +1939,7 @@ Value *CastToCStr(Value *V, Instruction &IP) {
// * memcmp(x,y,1) -> *x - *y // * memcmp(x,y,1) -> *x - *y
// //
// memmove: // memmove:
// * memmove(d,s,l,a) -> memcpy(d,s,l,a) // * memmove(d,s,l,a) -> memcpy(d,s,l,a)
// (if s is a global constant array) // (if s is a global constant array)
// //
// pow, powf, powl: // pow, powf, powl:
@ -1996,14 +1996,14 @@ Value *CastToCStr(Value *V, Instruction &IP) {
// //
// strstr: // strstr:
// * strstr(x,x) -> x // * strstr(x,x) -> x
// * strstr(s1,s2) -> offset_of_s2_in(s1) // * strstr(s1,s2) -> offset_of_s2_in(s1)
// (if s1 and s2 are constant strings) // (if s1 and s2 are constant strings)
// //
// tan, tanf, tanl: // tan, tanf, tanl:
// * tan(atan(x)) -> x // * tan(atan(x)) -> x
// //
// trunc, truncf, truncl: // trunc, truncf, truncl:
// * trunc(cnst) -> cnst' // * trunc(cnst) -> cnst'
// //
// //
} }

View File

@ -1319,7 +1319,7 @@ struct FoldSetCCLogical {
static bool MaskedValueIsZero(Value *V, ConstantIntegral *Mask) { static bool MaskedValueIsZero(Value *V, ConstantIntegral *Mask) {
// Note, we cannot consider 'undef' to be "IsZero" here. The problem is that // Note, we cannot consider 'undef' to be "IsZero" here. The problem is that
// we cannot optimize based on the assumption that it is zero without changing // we cannot optimize based on the assumption that it is zero without changing
// to to an explicit zero. If we don't change it to zero, other code could // to to an explicit zero. If we don't change it to zero, other code could
// optimized based on the contradictory assumption that it is non-zero. // optimized based on the contradictory assumption that it is non-zero.
// Because instcombine aggressively folds operations with undef args anyway, // Because instcombine aggressively folds operations with undef args anyway,
// this won't lose us code quality. // this won't lose us code quality.
@ -2308,7 +2308,7 @@ Instruction *InstCombiner::FoldGEPSetCC(User *GEPLHS, Value *RHS,
// compare the base pointer. // compare the base pointer.
if (PtrBase != GEPRHS->getOperand(0)) { if (PtrBase != GEPRHS->getOperand(0)) {
bool IndicesTheSame = GEPLHS->getNumOperands()==GEPRHS->getNumOperands(); bool IndicesTheSame = GEPLHS->getNumOperands()==GEPRHS->getNumOperands();
IndicesTheSame &= GEPLHS->getOperand(0)->getType() == IndicesTheSame &= GEPLHS->getOperand(0)->getType() ==
GEPRHS->getOperand(0)->getType(); GEPRHS->getOperand(0)->getType();
if (IndicesTheSame) if (IndicesTheSame)
for (unsigned i = 1, e = GEPLHS->getNumOperands(); i != e; ++i) for (unsigned i = 1, e = GEPLHS->getNumOperands(); i != e; ++i)
@ -3103,7 +3103,7 @@ Instruction *InstCombiner::visitSetCondInstWithCastAndCast(SetCondInst &SCI) {
} }
} }
// Finally, return the value computed. // Finally, return the value computed.
if (SCI.getOpcode() == Instruction::SetLT) { if (SCI.getOpcode() == Instruction::SetLT) {
return ReplaceInstUsesWith(SCI, Result); return ReplaceInstUsesWith(SCI, Result);
} else { } else {
@ -3167,7 +3167,7 @@ Instruction *InstCombiner::visitShiftInst(ShiftInst &I) {
return new CastInst(V, I.getType()); return new CastInst(V, I.getType());
} }
} }
if (ConstantUInt *CUI = dyn_cast<ConstantUInt>(Op1)) { if (ConstantUInt *CUI = dyn_cast<ConstantUInt>(Op1)) {
// shl uint X, 32 = 0 and shr ubyte Y, 9 = 0, ... just don't eliminate shr // shl uint X, 32 = 0 and shr ubyte Y, 9 = 0, ... just don't eliminate shr
// of a signed value. // of a signed value.
@ -3623,7 +3623,7 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) {
if (ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1)) { if (ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1)) {
if (Op1C->getRawValue() == 0) { if (Op1C->getRawValue() == 0) {
// If the input only has the low bit set, simplify directly. // If the input only has the low bit set, simplify directly.
Constant *Not1 = Constant *Not1 =
ConstantExpr::getNot(ConstantInt::get(Op0->getType(), 1)); ConstantExpr::getNot(ConstantInt::get(Op0->getType(), 1));
// cast (X != 0) to int --> X if X&~1 == 0 // cast (X != 0) to int --> X if X&~1 == 0
if (MaskedValueIsZero(Op0, cast<ConstantIntegral>(Not1))) { if (MaskedValueIsZero(Op0, cast<ConstantIntegral>(Not1))) {
@ -3666,7 +3666,7 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) {
if ((Op1C->getRawValue() & Op1C->getRawValue()-1) == 0) { if ((Op1C->getRawValue() & Op1C->getRawValue()-1) == 0) {
// cast (X == 1) to int -> X iff X has only the low bit set. // cast (X == 1) to int -> X iff X has only the low bit set.
if (Op1C->getRawValue() == 1) { if (Op1C->getRawValue() == 1) {
Constant *Not1 = Constant *Not1 =
ConstantExpr::getNot(ConstantInt::get(Op0->getType(), 1)); ConstantExpr::getNot(ConstantInt::get(Op0->getType(), 1));
if (MaskedValueIsZero(Op0, cast<ConstantIntegral>(Not1))) { if (MaskedValueIsZero(Op0, cast<ConstantIntegral>(Not1))) {
if (CI.getType() == Op0->getType()) if (CI.getType() == Op0->getType())
@ -5247,7 +5247,7 @@ bool InstCombiner::runOnFunction(Function &F) {
E = df_ext_end(&F.front(), Visited); BB != E; ++BB) E = df_ext_end(&F.front(), Visited); BB != E; ++BB)
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
WorkList.push_back(I); WorkList.push_back(I);
// Do a quick scan over the function. If we find any blocks that are // Do a quick scan over the function. If we find any blocks that are
// unreachable, remove any instructions inside of them. This prevents // unreachable, remove any instructions inside of them. This prevents
// the instcombine code from having to deal with some bad special cases. // the instcombine code from having to deal with some bad special cases.

View File

@ -121,7 +121,7 @@ unsigned Reassociate::getRank(Value *V) {
unsigned &CachedRank = ValueRankMap[I]; unsigned &CachedRank = ValueRankMap[I];
if (CachedRank) return CachedRank; // Rank already known? if (CachedRank) return CachedRank; // Rank already known?
// If this is an expression, return the 1+MAX(rank(LHS), rank(RHS)) so that // If this is an expression, return the 1+MAX(rank(LHS), rank(RHS)) so that
// we can reassociate expressions for code motion! Since we do not recurse // we can reassociate expressions for code motion! Since we do not recurse
// for PHI nodes, we cannot have infinite recursion here, because there // for PHI nodes, we cannot have infinite recursion here, because there
@ -130,7 +130,7 @@ unsigned Reassociate::getRank(Value *V) {
for (unsigned i = 0, e = I->getNumOperands(); for (unsigned i = 0, e = I->getNumOperands();
i != e && Rank != MaxRank; ++i) i != e && Rank != MaxRank; ++i)
Rank = std::max(Rank, getRank(I->getOperand(i))); Rank = std::max(Rank, getRank(I->getOperand(i)));
// If this is a not or neg instruction, do not count it for rank. This // If this is a not or neg instruction, do not count it for rank. This
// assures us that X and ~X will have the same rank. // assures us that X and ~X will have the same rank.
if (!I->getType()->isIntegral() || if (!I->getType()->isIntegral() ||
@ -139,7 +139,7 @@ unsigned Reassociate::getRank(Value *V) {
//DEBUG(std::cerr << "Calculated Rank[" << V->getName() << "] = " //DEBUG(std::cerr << "Calculated Rank[" << V->getName() << "] = "
//<< Rank << "\n"); //<< Rank << "\n");
return CachedRank = Rank; return CachedRank = Rank;
} }
@ -176,7 +176,7 @@ static Instruction *LowerNegateToMultiply(Instruction *Neg) {
void Reassociate::LinearizeExpr(BinaryOperator *I) { void Reassociate::LinearizeExpr(BinaryOperator *I) {
BinaryOperator *LHS = cast<BinaryOperator>(I->getOperand(0)); BinaryOperator *LHS = cast<BinaryOperator>(I->getOperand(0));
BinaryOperator *RHS = cast<BinaryOperator>(I->getOperand(1)); BinaryOperator *RHS = cast<BinaryOperator>(I->getOperand(1));
assert(isReassociableOp(LHS, I->getOpcode()) && assert(isReassociableOp(LHS, I->getOpcode()) &&
isReassociableOp(RHS, I->getOpcode()) && isReassociableOp(RHS, I->getOpcode()) &&
"Not an expression that needs linearization?"); "Not an expression that needs linearization?");
@ -190,7 +190,7 @@ void Reassociate::LinearizeExpr(BinaryOperator *I) {
I->setOperand(1, RHS->getOperand(0)); I->setOperand(1, RHS->getOperand(0));
RHS->setOperand(0, LHS); RHS->setOperand(0, LHS);
I->setOperand(0, RHS); I->setOperand(0, RHS);
++NumLinear; ++NumLinear;
MadeChange = true; MadeChange = true;
DEBUG(std::cerr << "Linearized: " << *I); DEBUG(std::cerr << "Linearized: " << *I);
@ -363,7 +363,7 @@ static Instruction *BreakUpSubtract(Instruction *Sub) {
// Everyone now refers to the add instruction. // Everyone now refers to the add instruction.
Sub->replaceAllUsesWith(New); Sub->replaceAllUsesWith(New);
Sub->eraseFromParent(); Sub->eraseFromParent();
DEBUG(std::cerr << "Negated: " << *New); DEBUG(std::cerr << "Negated: " << *New);
return New; return New;
} }
@ -536,7 +536,7 @@ void Reassociate::OptimizeExpression(unsigned Opcode,
//case Instruction::Mul: //case Instruction::Mul:
} }
if (IterateOptimization) if (IterateOptimization)
OptimizeExpression(Opcode, Ops); OptimizeExpression(Opcode, Ops);
} }
@ -590,13 +590,13 @@ void Reassociate::ReassociateBB(BasicBlock *BB) {
// If this instruction is a commutative binary operator, process it. // If this instruction is a commutative binary operator, process it.
if (!BI->isAssociative()) continue; if (!BI->isAssociative()) continue;
BinaryOperator *I = cast<BinaryOperator>(BI); BinaryOperator *I = cast<BinaryOperator>(BI);
// If this is an interior node of a reassociable tree, ignore it until we // If this is an interior node of a reassociable tree, ignore it until we
// get to the root of the tree, to avoid N^2 analysis. // get to the root of the tree, to avoid N^2 analysis.
if (I->hasOneUse() && isReassociableOp(I->use_back(), I->getOpcode())) if (I->hasOneUse() && isReassociableOp(I->use_back(), I->getOpcode()))
continue; continue;
// First, walk the expression tree, linearizing the tree, collecting // First, walk the expression tree, linearizing the tree, collecting
std::vector<ValueEntry> Ops; std::vector<ValueEntry> Ops;
LinearizeExprTree(I, Ops); LinearizeExprTree(I, Ops);
@ -619,7 +619,7 @@ void Reassociate::ReassociateBB(BasicBlock *BB) {
// this is a multiply tree used only by an add, and the immediate is a -1. // this is a multiply tree used only by an add, and the immediate is a -1.
// In this case we reassociate to put the negation on the outside so that we // In this case we reassociate to put the negation on the outside so that we
// can fold the negation into the add: (-X)*Y + Z -> Z-X*Y // can fold the negation into the add: (-X)*Y + Z -> Z-X*Y
if (I->getOpcode() == Instruction::Mul && I->hasOneUse() && if (I->getOpcode() == Instruction::Mul && I->hasOneUse() &&
cast<Instruction>(I->use_back())->getOpcode() == Instruction::Add && cast<Instruction>(I->use_back())->getOpcode() == Instruction::Add &&
isa<ConstantInt>(Ops.back().Op) && isa<ConstantInt>(Ops.back().Op) &&
cast<ConstantInt>(Ops.back().Op)->isAllOnesValue()) { cast<ConstantInt>(Ops.back().Op)->isAllOnesValue()) {

View File

@ -117,7 +117,7 @@ bool TailCallElim::runOnFunction(Function &F) {
for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
if (!FunctionContainsEscapingAllocas) if (!FunctionContainsEscapingAllocas)
FunctionContainsEscapingAllocas = CheckForEscapingAllocas(BB); FunctionContainsEscapingAllocas = CheckForEscapingAllocas(BB);
if (ReturnInst *Ret = dyn_cast<ReturnInst>(BB->getTerminator())) if (ReturnInst *Ret = dyn_cast<ReturnInst>(BB->getTerminator()))
MadeChange |= ProcessReturningBlock(Ret, OldEntry, ArgumentPHIs); MadeChange |= ProcessReturningBlock(Ret, OldEntry, ArgumentPHIs);
} }

View File

@ -55,7 +55,7 @@ Module *llvm::CloneModule(const Module *M) {
// Loop over the functions in the module, making external functions as before // Loop over the functions in the module, making external functions as before
for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) { for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) {
Function *NF = Function *NF =
new Function(cast<FunctionType>(I->getType()->getElementType()), new Function(cast<FunctionType>(I->getType()->getElementType()),
GlobalValue::ExternalLinkage, I->getName(), New); GlobalValue::ExternalLinkage, I->getName(), New);
NF->setCallingConv(I->getCallingConv()); NF->setCallingConv(I->getCallingConv());

View File

@ -107,7 +107,7 @@ bool llvm::InlineFunction(CallSite CS) {
} }
} }
// If we are inlining tail call instruction through an invoke or // If we are inlining tail call instruction through an invoke or
if (MustClearTailCallFlags) { if (MustClearTailCallFlags) {
for (Function::iterator BB = FirstNewBlock, E = Caller->end(); for (Function::iterator BB = FirstNewBlock, E = Caller->end();
BB != E; ++BB) BB != E; ++BB)

View File

@ -245,10 +245,10 @@ bool llvm::canConstantFoldCallTo(Function *F) {
switch (Name[0]) switch (Name[0])
{ {
case 'a': case 'a':
return Name == "acos" || Name == "asin" || Name == "atan" || return Name == "acos" || Name == "asin" || Name == "atan" ||
Name == "atan2"; Name == "atan2";
case 'c': case 'c':
return Name == "ceil" || Name == "cos" || Name == "cosf" || return Name == "ceil" || Name == "cos" || Name == "cosf" ||
Name == "cosh"; Name == "cosh";
case 'e': case 'e':
return Name == "exp"; return Name == "exp";
@ -374,7 +374,7 @@ Constant *llvm::ConstantFoldCall(Function *F,
bool llvm::isInstructionTriviallyDead(Instruction *I) { bool llvm::isInstructionTriviallyDead(Instruction *I) {
if (!I->use_empty() || isa<TerminatorInst>(I)) return false; if (!I->use_empty() || isa<TerminatorInst>(I)) return false;
if (!I->mayWriteToMemory()) return true; if (!I->mayWriteToMemory()) return true;
if (CallInst *CI = dyn_cast<CallInst>(I)) if (CallInst *CI = dyn_cast<CallInst>(I))

View File

@ -665,7 +665,7 @@ void llvm::PromoteMemToReg(const std::vector<AllocaInst*> &Allocas,
// undef into the alloca right after the alloca itself. // undef into the alloca right after the alloca itself.
for (unsigned i = 0, e = RetryList.size(); i != e; ++i) { for (unsigned i = 0, e = RetryList.size(); i != e; ++i) {
BasicBlock::iterator BBI = RetryList[i]; BasicBlock::iterator BBI = RetryList[i];
new StoreInst(UndefValue::get(RetryList[i]->getAllocatedType()), new StoreInst(UndefValue::get(RetryList[i]->getAllocatedType()),
RetryList[i], ++BBI); RetryList[i], ++BBI);
} }

View File

@ -143,8 +143,8 @@ unsigned Type::getPrimitiveSize() const {
case Type::UByteTyID: return 1; case Type::UByteTyID: return 1;
case Type::UShortTyID: case Type::UShortTyID:
case Type::ShortTyID: return 2; case Type::ShortTyID: return 2;
case Type::FloatTyID: case Type::FloatTyID:
case Type::IntTyID: case Type::IntTyID:
case Type::UIntTyID: return 4; case Type::UIntTyID: return 4;
case Type::LongTyID: case Type::LongTyID:
case Type::ULongTyID: case Type::ULongTyID:
@ -160,7 +160,7 @@ unsigned Type::getPrimitiveSizeInBits() const {
case Type::UByteTyID: return 8; case Type::UByteTyID: return 8;
case Type::UShortTyID: case Type::UShortTyID:
case Type::ShortTyID: return 16; case Type::ShortTyID: return 16;
case Type::FloatTyID: case Type::FloatTyID:
case Type::IntTyID: case Type::IntTyID:
case Type::UIntTyID: return 32; case Type::UIntTyID: return 32;
case Type::LongTyID: case Type::LongTyID:

View File

@ -324,7 +324,7 @@ bool BugDriver::diffProgram(const std::string &BytecodeFile,
Output.eraseFromDisk(); Output.eraseFromDisk();
// Remove the bytecode file if we are supposed to. // Remove the bytecode file if we are supposed to.
if (RemoveBytecode) if (RemoveBytecode)
sys::Path(BytecodeFile).eraseFromDisk(); sys::Path(BytecodeFile).eraseFromDisk();
return FilesDifferent; return FilesDifferent;
} }

View File

@ -692,7 +692,7 @@ static void CleanupAndPrepareModules(BugDriver &BD, Module *&Test,
GlobalVariable *Cache = GlobalVariable *Cache =
new GlobalVariable(F->getType(), false,GlobalValue::InternalLinkage, new GlobalVariable(F->getType(), false,GlobalValue::InternalLinkage,
NullPtr,F->getName()+".fpcache", F->getParent()); NullPtr,F->getName()+".fpcache", F->getParent());
// Construct a new stub function that will re-route calls to F // Construct a new stub function that will re-route calls to F
const FunctionType *FuncTy = F->getFunctionType(); const FunctionType *FuncTy = F->getFunctionType();
Function *FuncWrapper = new Function(FuncTy, Function *FuncWrapper = new Function(FuncTy,
@ -702,13 +702,13 @@ static void CleanupAndPrepareModules(BugDriver &BD, Module *&Test,
BasicBlock *EntryBB = new BasicBlock("entry", FuncWrapper); BasicBlock *EntryBB = new BasicBlock("entry", FuncWrapper);
BasicBlock *DoCallBB = new BasicBlock("usecache", FuncWrapper); BasicBlock *DoCallBB = new BasicBlock("usecache", FuncWrapper);
BasicBlock *LookupBB = new BasicBlock("lookupfp", FuncWrapper); BasicBlock *LookupBB = new BasicBlock("lookupfp", FuncWrapper);
// Check to see if we already looked up the value. // Check to see if we already looked up the value.
Value *CachedVal = new LoadInst(Cache, "fpcache", EntryBB); Value *CachedVal = new LoadInst(Cache, "fpcache", EntryBB);
Value *IsNull = new SetCondInst(Instruction::SetEQ, CachedVal, Value *IsNull = new SetCondInst(Instruction::SetEQ, CachedVal,
NullPtr, "isNull", EntryBB); NullPtr, "isNull", EntryBB);
new BranchInst(LookupBB, DoCallBB, IsNull, EntryBB); new BranchInst(LookupBB, DoCallBB, IsNull, EntryBB);
// Resolve the call to function F via the JIT API: // Resolve the call to function F via the JIT API:
// //
// call resolver(GetElementPtr...) // call resolver(GetElementPtr...)
@ -721,11 +721,11 @@ static void CleanupAndPrepareModules(BugDriver &BD, Module *&Test,
// Save the value in our cache. // Save the value in our cache.
new StoreInst(CastedResolver, Cache, LookupBB); new StoreInst(CastedResolver, Cache, LookupBB);
new BranchInst(DoCallBB, LookupBB); new BranchInst(DoCallBB, LookupBB);
PHINode *FuncPtr = new PHINode(NullPtr->getType(), "fp", DoCallBB); PHINode *FuncPtr = new PHINode(NullPtr->getType(), "fp", DoCallBB);
FuncPtr->addIncoming(CastedResolver, LookupBB); FuncPtr->addIncoming(CastedResolver, LookupBB);
FuncPtr->addIncoming(CachedVal, EntryBB); FuncPtr->addIncoming(CachedVal, EntryBB);
// Save the argument list. // Save the argument list.
std::vector<Value*> Args; std::vector<Value*> Args;
for (Function::arg_iterator i = FuncWrapper->arg_begin(), for (Function::arg_iterator i = FuncWrapper->arg_begin(),
@ -740,7 +740,7 @@ static void CleanupAndPrepareModules(BugDriver &BD, Module *&Test,
CallInst *Call = new CallInst(FuncPtr, Args, "retval", DoCallBB); CallInst *Call = new CallInst(FuncPtr, Args, "retval", DoCallBB);
new ReturnInst(Call, DoCallBB); new ReturnInst(Call, DoCallBB);
} }
// Use the wrapper function instead of the old function // Use the wrapper function instead of the old function
F->replaceAllUsesWith(FuncWrapper); F->replaceAllUsesWith(FuncWrapper);
} }

View File

@ -302,7 +302,7 @@ private:
tmp.replace(0,9,LLVMGXX); tmp.replace(0,9,LLVMGXX);
else if (*PI == "%llvmcc1%") else if (*PI == "%llvmcc1%")
tmp.replace(0,9,LLVMCC1); tmp.replace(0,9,LLVMCC1);
else if (*PI == "%llvmcc1plus%") else if (*PI == "%llvmcc1plus%")
tmp.replace(0,9,LLVMCC1); tmp.replace(0,9,LLVMCC1);
else else
found = false; found = false;

View File

@ -343,7 +343,7 @@ int main(int argc, char **argv) {
if (filePos != 0 && (libPos == 0 || filePos < libPos)) { if (filePos != 0 && (libPos == 0 || filePos < libPos)) {
// Add a source file // Add a source file
InpList.push_back(std::make_pair(*fileIt, InpList.push_back(std::make_pair(*fileIt,
GetFileType(*fileIt, filePos))); GetFileType(*fileIt, filePos)));
++fileIt; ++fileIt;
} else if ( libPos != 0 && (filePos == 0 || libPos < filePos) ) { } else if ( libPos != 0 && (filePos == 0 || libPos < filePos) ) {

View File

@ -116,7 +116,7 @@ AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI, unsigned Variant) {
LastEmitted = DollarPos; LastEmitted = DollarPos;
} else if (AsmString[DollarPos] == '{') { } else if (AsmString[DollarPos] == '{') {
if (inVariant) if (inVariant)
throw "Nested variants found for instruction '" + throw "Nested variants found for instruction '" +
CGI.TheDef->getName() + "'!"; CGI.TheDef->getName() + "'!";
LastEmitted = DollarPos+1; LastEmitted = DollarPos+1;
inVariant = true; // We are now inside of the variant! inVariant = true; // We are now inside of the variant!
@ -127,7 +127,7 @@ AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI, unsigned Variant) {
std::string::size_type NP = std::string::size_type NP =
AsmString.find_first_of("|}", LastEmitted); AsmString.find_first_of("|}", LastEmitted);
if (NP == std::string::npos) if (NP == std::string::npos)
throw "Incomplete variant for instruction '" + throw "Incomplete variant for instruction '" +
CGI.TheDef->getName() + "'!"; CGI.TheDef->getName() + "'!";
LastEmitted = NP+1; LastEmitted = NP+1;
if (AsmString[NP] == '}') { if (AsmString[NP] == '}') {
@ -142,7 +142,7 @@ AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI, unsigned Variant) {
// Move to the end of variant list. // Move to the end of variant list.
std::string::size_type NP = AsmString.find('}', LastEmitted); std::string::size_type NP = AsmString.find('}', LastEmitted);
if (NP == std::string::npos) if (NP == std::string::npos)
throw "Incomplete variant for instruction '" + throw "Incomplete variant for instruction '" +
CGI.TheDef->getName() + "'!"; CGI.TheDef->getName() + "'!";
LastEmitted = NP+1; LastEmitted = NP+1;
inVariant = false; inVariant = false;
@ -188,7 +188,7 @@ AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI, unsigned Variant) {
++VarEnd; ++VarEnd;
} }
if (VarName.empty()) if (VarName.empty())
throw "Stray '$' in '" + CGI.TheDef->getName() + throw "Stray '$' in '" + CGI.TheDef->getName() +
"' asm string, maybe you want $$?"; "' asm string, maybe you want $$?";
unsigned OpNo = CGI.getOperandNamed(VarName); unsigned OpNo = CGI.getOperandNamed(VarName);