* Add support for indexing into structures, thanks to Chris (x86)

The large diff is because of indentation of a whole region
* Fix querying predecessor blocks in SelectPHINodes(), thanks to Brian (v8)
* Add support for external functions malloc() and free()
* Fix some code indentation

Remember, kids: It's not plagiarism if you "creatively borrow" from your
sources.  It's called "research"!

llvm-svn: 14723
This commit is contained in:
Misha Brukman 2004-07-09 15:45:07 +00:00
parent 14d02cd2d8
commit 82a065dc41
2 changed files with 186 additions and 118 deletions

View File

@ -76,11 +76,11 @@ namespace {
int VarArgsFrameIndex; // FrameIndex for start of varargs area
int ReturnAddressIndex; // FrameIndex for the return address
std::map<Value*, unsigned> RegMap; // Mapping between Val's and SSA Regs
std::map<Value*, unsigned> RegMap; // Mapping between Values and SSA Regs
// External functions used in the Module
Function *fmodFn, *__moddi3Fn, *__divdi3Fn, *__umoddi3Fn, *__udivdi3Fn,
*__fixdfdiFn, *__floatdisfFn, *__floatdidfFn;
*__fixdfdiFn, *__floatdisfFn, *__floatdidfFn, *mallocFn, *freeFn;
// MBBMap - Mapping between LLVM BB -> Machine BB
std::map<const BasicBlock*, MachineBasicBlock*> MBBMap;
@ -97,6 +97,7 @@ namespace {
Type *f = Type::FloatTy;
Type *l = Type::LongTy;
Type *ul = Type::ULongTy;
Type *voidPtr = PointerType::get(Type::SByteTy);
// double fmod(double, double);
fmodFn = M.getOrInsertFunction("fmod", d, d, d, 0);
// long __moddi3(long, long);
@ -113,6 +114,10 @@ namespace {
__floatdisfFn = M.getOrInsertFunction("__floatdisf", f, l, 0);
// double __floatdidf(long)
__floatdidfFn = M.getOrInsertFunction("__floatdidf", d, l, 0);
// void* malloc(size_t)
mallocFn = M.getOrInsertFunction("malloc", voidPtr, Type::UIntTy, 0);
// void free(void*)
freeFn = M.getOrInsertFunction("free", Type::VoidTy, voidPtr, 0);
return false;
}
@ -594,13 +599,13 @@ void ISel::LoadArgumentsToVirtualRegs(Function &Fn) {
if (ArgLive) {
FI = MFI->CreateFixedObject(8, ArgOffset);
if (GPR_remaining > 1) {
BuildMI(BB, PPC32::OR, 2, Reg).addReg(GPR[GPR_idx])
.addReg(GPR[GPR_idx]);
BuildMI(BB, PPC32::OR, 2, Reg+1).addReg(GPR[GPR_idx+1])
.addReg(GPR[GPR_idx+1]);
BuildMI(BB, PPC32::OR, 2, Reg).addReg(GPR[GPR_idx])
.addReg(GPR[GPR_idx]);
BuildMI(BB, PPC32::OR, 2, Reg+1).addReg(GPR[GPR_idx+1])
.addReg(GPR[GPR_idx+1]);
} else {
addFrameReference(BuildMI(BB, PPC32::LWZ, 2, Reg), FI);
addFrameReference(BuildMI(BB, PPC32::LWZ, 2, Reg+1), FI, 4);
addFrameReference(BuildMI(BB, PPC32::LWZ, 2, Reg), FI);
addFrameReference(BuildMI(BB, PPC32::LWZ, 2, Reg+1), FI, 4);
}
}
ArgOffset += 4; // longs require 4 additional bytes
@ -686,7 +691,15 @@ void ISel::SelectPHINodes() {
std::map<MachineBasicBlock*, unsigned> PHIValues;
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
MachineBasicBlock *PredMBB = MBBMap[PN->getIncomingBlock(i)];
MachineBasicBlock *PredMBB = 0;
for (MachineBasicBlock::pred_iterator PI = MBB.pred_begin (),
PE = MBB.pred_end (); PI != PE; ++PI)
if (PN->getIncomingBlock(i) == (*PI)->getBasicBlock()) {
PredMBB = *PI;
break;
}
assert (PredMBB && "Couldn't find incoming machine-cfg edge for phi");
unsigned ValReg;
std::map<MachineBasicBlock*, unsigned>::iterator EntryIt =
PHIValues.lower_bound(PredMBB);
@ -2494,8 +2507,9 @@ void ISel::emitCastOperation(MachineBasicBlock *BB,
if (SrcClass == cLong) {
std::vector<ValueRecord> Args;
Args.push_back(ValueRecord(SrcReg, SrcTy));
Function *floatFn = (SrcTy==Type::FloatTy) ? __floatdisfFn : __floatdidfFn;
MachineInstr *TheCall =
BuildMI(PPC32::CALLpcrel, 1).addGlobalAddress(__floatdidfFn, true);
BuildMI(PPC32::CALLpcrel, 1).addGlobalAddress(floatFn, true);
doCall(ValueRecord(DestReg, DestTy), TheCall, Args, false);
return;
}
@ -2703,58 +2717,78 @@ void ISel::emitGEPOperation(MachineBasicBlock *MBB,
BuildMI(*MBB, IP, PPC32::OR, 2, TargetReg).addReg(Reg).addReg(Reg);
break; // we are now done
}
// It's an array or pointer access: [ArraySize x ElementType].
const SequentialType *SqTy = cast<SequentialType>(GEPTypes.back());
Value *idx = GEPOps.back();
GEPOps.pop_back(); // Consume a GEP operand
GEPTypes.pop_back();
if (const StructType *StTy = dyn_cast<StructType>(GEPTypes.back())) {
// It's a struct access. CUI is the index into the structure,
// which names the field. This index must have unsigned type.
const ConstantUInt *CUI = cast<ConstantUInt>(GEPOps.back());
// Many GEP instructions use a [cast (int/uint) to LongTy] as their
// operand. Handle this case directly now...
if (CastInst *CI = dyn_cast<CastInst>(idx))
if (CI->getOperand(0)->getType() == Type::IntTy ||
CI->getOperand(0)->getType() == Type::UIntTy)
idx = CI->getOperand(0);
// We want to add BaseReg to(idxReg * sizeof ElementType). First, we
// must find the size of the pointed-to type (Not coincidentally, the next
// type is the type of the elements in the array).
const Type *ElTy = SqTy->getElementType();
unsigned elementSize = TD.getTypeSize(ElTy);
if (idx == Constant::getNullValue(idx->getType())) {
// GEP with idx 0 is a no-op
} else if (elementSize == 1) {
// If the element size is 1, we don't have to multiply, just add
unsigned idxReg = getReg(idx, MBB, IP);
// Use the TargetData structure to pick out what the layout of the
// structure is in memory. Since the structure index must be constant, we
// can get its value and use it to find the right byte offset from the
// StructLayout class's list of structure member offsets.
unsigned Disp = TD.getStructLayout(StTy)->MemberOffsets[CUI->getValue()];
GEPOps.pop_back(); // Consume a GEP operand
GEPTypes.pop_back();
unsigned Reg = makeAnotherReg(Type::UIntTy);
BuildMI(*MBB, IP, PPC32::ADD, 2,TargetReg).addReg(Reg).addReg(idxReg);
unsigned DispReg = makeAnotherReg(Type::UIntTy);
BuildMI(*MBB, IP, PPC32::LI, 2, DispReg).addImm(Disp);
BuildMI(*MBB, IP, PPC32::ADD, 2, TargetReg).addReg(Reg).addReg(DispReg);
--IP; // Insert the next instruction before this one.
TargetReg = Reg; // Codegen the rest of the GEP into this
} else {
unsigned idxReg = getReg(idx, MBB, IP);
unsigned OffsetReg = makeAnotherReg(Type::UIntTy);
// Make sure we can back the iterator up to point to the first
// instruction emitted.
MachineBasicBlock::iterator BeforeIt = IP;
if (IP == MBB->begin())
BeforeIt = MBB->end();
else
--BeforeIt;
doMultiplyConst(MBB, IP, OffsetReg, Type::IntTy, idxReg, elementSize);
// Emit an ADD to add OffsetReg to the basePtr.
unsigned Reg = makeAnotherReg(Type::UIntTy);
BuildMI(*MBB, IP, PPC32::ADD, 2, TargetReg).addReg(Reg).addReg(OffsetReg);
// Step to the first instruction of the multiply.
if (BeforeIt == MBB->end())
IP = MBB->begin();
else
IP = ++BeforeIt;
TargetReg = Reg; // Codegen the rest of the GEP into this
// It's an array or pointer access: [ArraySize x ElementType].
const SequentialType *SqTy = cast<SequentialType>(GEPTypes.back());
Value *idx = GEPOps.back();
GEPOps.pop_back(); // Consume a GEP operand
GEPTypes.pop_back();
// Many GEP instructions use a [cast (int/uint) to LongTy] as their
// operand. Handle this case directly now...
if (CastInst *CI = dyn_cast<CastInst>(idx))
if (CI->getOperand(0)->getType() == Type::IntTy ||
CI->getOperand(0)->getType() == Type::UIntTy)
idx = CI->getOperand(0);
// We want to add BaseReg to(idxReg * sizeof ElementType). First, we
// must find the size of the pointed-to type (Not coincidentally, the next
// type is the type of the elements in the array).
const Type *ElTy = SqTy->getElementType();
unsigned elementSize = TD.getTypeSize(ElTy);
if (idx == Constant::getNullValue(idx->getType())) {
// GEP with idx 0 is a no-op
} else if (elementSize == 1) {
// If the element size is 1, we don't have to multiply, just add
unsigned idxReg = getReg(idx, MBB, IP);
unsigned Reg = makeAnotherReg(Type::UIntTy);
BuildMI(*MBB, IP, PPC32::ADD, 2,TargetReg).addReg(Reg).addReg(idxReg);
--IP; // Insert the next instruction before this one.
TargetReg = Reg; // Codegen the rest of the GEP into this
} else {
unsigned idxReg = getReg(idx, MBB, IP);
unsigned OffsetReg = makeAnotherReg(Type::UIntTy);
// Make sure we can back the iterator up to point to the first
// instruction emitted.
MachineBasicBlock::iterator BeforeIt = IP;
if (IP == MBB->begin())
BeforeIt = MBB->end();
else
--BeforeIt;
doMultiplyConst(MBB, IP, OffsetReg, Type::IntTy, idxReg, elementSize);
// Emit an ADD to add OffsetReg to the basePtr.
unsigned Reg = makeAnotherReg(Type::UIntTy);
BuildMI(*MBB, IP, PPC32::ADD, 2, TargetReg).addReg(Reg).addReg(OffsetReg);
// Step to the first instruction of the multiply.
if (BeforeIt == MBB->end())
IP = MBB->begin();
else
IP = ++BeforeIt;
TargetReg = Reg; // Codegen the rest of the GEP into this
}
}
}
}
@ -2821,7 +2855,7 @@ void ISel::visitMallocInst(MallocInst &I) {
std::vector<ValueRecord> Args;
Args.push_back(ValueRecord(Arg, Type::UIntTy));
MachineInstr *TheCall =
BuildMI(PPC32::CALLpcrel, 1).addExternalSymbol("malloc", true);
BuildMI(PPC32::CALLpcrel, 1).addGlobalAddress(mallocFn, true);
doCall(ValueRecord(getReg(I), I.getType()), TheCall, Args, false);
}
@ -2833,7 +2867,7 @@ void ISel::visitFreeInst(FreeInst &I) {
std::vector<ValueRecord> Args;
Args.push_back(ValueRecord(I.getOperand(0)));
MachineInstr *TheCall =
BuildMI(PPC32::CALLpcrel, 1).addExternalSymbol("free", true);
BuildMI(PPC32::CALLpcrel, 1).addGlobalAddress(freeFn, true);
doCall(ValueRecord(0, Type::VoidTy), TheCall, Args, false);
}

View File

@ -76,11 +76,11 @@ namespace {
int VarArgsFrameIndex; // FrameIndex for start of varargs area
int ReturnAddressIndex; // FrameIndex for the return address
std::map<Value*, unsigned> RegMap; // Mapping between Val's and SSA Regs
std::map<Value*, unsigned> RegMap; // Mapping between Values and SSA Regs
// External functions used in the Module
Function *fmodFn, *__moddi3Fn, *__divdi3Fn, *__umoddi3Fn, *__udivdi3Fn,
*__fixdfdiFn, *__floatdisfFn, *__floatdidfFn;
*__fixdfdiFn, *__floatdisfFn, *__floatdidfFn, *mallocFn, *freeFn;
// MBBMap - Mapping between LLVM BB -> Machine BB
std::map<const BasicBlock*, MachineBasicBlock*> MBBMap;
@ -97,6 +97,7 @@ namespace {
Type *f = Type::FloatTy;
Type *l = Type::LongTy;
Type *ul = Type::ULongTy;
Type *voidPtr = PointerType::get(Type::SByteTy);
// double fmod(double, double);
fmodFn = M.getOrInsertFunction("fmod", d, d, d, 0);
// long __moddi3(long, long);
@ -113,6 +114,10 @@ namespace {
__floatdisfFn = M.getOrInsertFunction("__floatdisf", f, l, 0);
// double __floatdidf(long)
__floatdidfFn = M.getOrInsertFunction("__floatdidf", d, l, 0);
// void* malloc(size_t)
mallocFn = M.getOrInsertFunction("malloc", voidPtr, Type::UIntTy, 0);
// void free(void*)
freeFn = M.getOrInsertFunction("free", Type::VoidTy, voidPtr, 0);
return false;
}
@ -594,13 +599,13 @@ void ISel::LoadArgumentsToVirtualRegs(Function &Fn) {
if (ArgLive) {
FI = MFI->CreateFixedObject(8, ArgOffset);
if (GPR_remaining > 1) {
BuildMI(BB, PPC32::OR, 2, Reg).addReg(GPR[GPR_idx])
.addReg(GPR[GPR_idx]);
BuildMI(BB, PPC32::OR, 2, Reg+1).addReg(GPR[GPR_idx+1])
.addReg(GPR[GPR_idx+1]);
BuildMI(BB, PPC32::OR, 2, Reg).addReg(GPR[GPR_idx])
.addReg(GPR[GPR_idx]);
BuildMI(BB, PPC32::OR, 2, Reg+1).addReg(GPR[GPR_idx+1])
.addReg(GPR[GPR_idx+1]);
} else {
addFrameReference(BuildMI(BB, PPC32::LWZ, 2, Reg), FI);
addFrameReference(BuildMI(BB, PPC32::LWZ, 2, Reg+1), FI, 4);
addFrameReference(BuildMI(BB, PPC32::LWZ, 2, Reg), FI);
addFrameReference(BuildMI(BB, PPC32::LWZ, 2, Reg+1), FI, 4);
}
}
ArgOffset += 4; // longs require 4 additional bytes
@ -686,7 +691,15 @@ void ISel::SelectPHINodes() {
std::map<MachineBasicBlock*, unsigned> PHIValues;
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
MachineBasicBlock *PredMBB = MBBMap[PN->getIncomingBlock(i)];
MachineBasicBlock *PredMBB = 0;
for (MachineBasicBlock::pred_iterator PI = MBB.pred_begin (),
PE = MBB.pred_end (); PI != PE; ++PI)
if (PN->getIncomingBlock(i) == (*PI)->getBasicBlock()) {
PredMBB = *PI;
break;
}
assert (PredMBB && "Couldn't find incoming machine-cfg edge for phi");
unsigned ValReg;
std::map<MachineBasicBlock*, unsigned>::iterator EntryIt =
PHIValues.lower_bound(PredMBB);
@ -2494,8 +2507,9 @@ void ISel::emitCastOperation(MachineBasicBlock *BB,
if (SrcClass == cLong) {
std::vector<ValueRecord> Args;
Args.push_back(ValueRecord(SrcReg, SrcTy));
Function *floatFn = (SrcTy==Type::FloatTy) ? __floatdisfFn : __floatdidfFn;
MachineInstr *TheCall =
BuildMI(PPC32::CALLpcrel, 1).addGlobalAddress(__floatdidfFn, true);
BuildMI(PPC32::CALLpcrel, 1).addGlobalAddress(floatFn, true);
doCall(ValueRecord(DestReg, DestTy), TheCall, Args, false);
return;
}
@ -2703,58 +2717,78 @@ void ISel::emitGEPOperation(MachineBasicBlock *MBB,
BuildMI(*MBB, IP, PPC32::OR, 2, TargetReg).addReg(Reg).addReg(Reg);
break; // we are now done
}
// It's an array or pointer access: [ArraySize x ElementType].
const SequentialType *SqTy = cast<SequentialType>(GEPTypes.back());
Value *idx = GEPOps.back();
GEPOps.pop_back(); // Consume a GEP operand
GEPTypes.pop_back();
if (const StructType *StTy = dyn_cast<StructType>(GEPTypes.back())) {
// It's a struct access. CUI is the index into the structure,
// which names the field. This index must have unsigned type.
const ConstantUInt *CUI = cast<ConstantUInt>(GEPOps.back());
// Many GEP instructions use a [cast (int/uint) to LongTy] as their
// operand. Handle this case directly now...
if (CastInst *CI = dyn_cast<CastInst>(idx))
if (CI->getOperand(0)->getType() == Type::IntTy ||
CI->getOperand(0)->getType() == Type::UIntTy)
idx = CI->getOperand(0);
// We want to add BaseReg to(idxReg * sizeof ElementType). First, we
// must find the size of the pointed-to type (Not coincidentally, the next
// type is the type of the elements in the array).
const Type *ElTy = SqTy->getElementType();
unsigned elementSize = TD.getTypeSize(ElTy);
if (idx == Constant::getNullValue(idx->getType())) {
// GEP with idx 0 is a no-op
} else if (elementSize == 1) {
// If the element size is 1, we don't have to multiply, just add
unsigned idxReg = getReg(idx, MBB, IP);
// Use the TargetData structure to pick out what the layout of the
// structure is in memory. Since the structure index must be constant, we
// can get its value and use it to find the right byte offset from the
// StructLayout class's list of structure member offsets.
unsigned Disp = TD.getStructLayout(StTy)->MemberOffsets[CUI->getValue()];
GEPOps.pop_back(); // Consume a GEP operand
GEPTypes.pop_back();
unsigned Reg = makeAnotherReg(Type::UIntTy);
BuildMI(*MBB, IP, PPC32::ADD, 2,TargetReg).addReg(Reg).addReg(idxReg);
unsigned DispReg = makeAnotherReg(Type::UIntTy);
BuildMI(*MBB, IP, PPC32::LI, 2, DispReg).addImm(Disp);
BuildMI(*MBB, IP, PPC32::ADD, 2, TargetReg).addReg(Reg).addReg(DispReg);
--IP; // Insert the next instruction before this one.
TargetReg = Reg; // Codegen the rest of the GEP into this
} else {
unsigned idxReg = getReg(idx, MBB, IP);
unsigned OffsetReg = makeAnotherReg(Type::UIntTy);
// Make sure we can back the iterator up to point to the first
// instruction emitted.
MachineBasicBlock::iterator BeforeIt = IP;
if (IP == MBB->begin())
BeforeIt = MBB->end();
else
--BeforeIt;
doMultiplyConst(MBB, IP, OffsetReg, Type::IntTy, idxReg, elementSize);
// Emit an ADD to add OffsetReg to the basePtr.
unsigned Reg = makeAnotherReg(Type::UIntTy);
BuildMI(*MBB, IP, PPC32::ADD, 2, TargetReg).addReg(Reg).addReg(OffsetReg);
// Step to the first instruction of the multiply.
if (BeforeIt == MBB->end())
IP = MBB->begin();
else
IP = ++BeforeIt;
TargetReg = Reg; // Codegen the rest of the GEP into this
// It's an array or pointer access: [ArraySize x ElementType].
const SequentialType *SqTy = cast<SequentialType>(GEPTypes.back());
Value *idx = GEPOps.back();
GEPOps.pop_back(); // Consume a GEP operand
GEPTypes.pop_back();
// Many GEP instructions use a [cast (int/uint) to LongTy] as their
// operand. Handle this case directly now...
if (CastInst *CI = dyn_cast<CastInst>(idx))
if (CI->getOperand(0)->getType() == Type::IntTy ||
CI->getOperand(0)->getType() == Type::UIntTy)
idx = CI->getOperand(0);
// We want to add BaseReg to(idxReg * sizeof ElementType). First, we
// must find the size of the pointed-to type (Not coincidentally, the next
// type is the type of the elements in the array).
const Type *ElTy = SqTy->getElementType();
unsigned elementSize = TD.getTypeSize(ElTy);
if (idx == Constant::getNullValue(idx->getType())) {
// GEP with idx 0 is a no-op
} else if (elementSize == 1) {
// If the element size is 1, we don't have to multiply, just add
unsigned idxReg = getReg(idx, MBB, IP);
unsigned Reg = makeAnotherReg(Type::UIntTy);
BuildMI(*MBB, IP, PPC32::ADD, 2,TargetReg).addReg(Reg).addReg(idxReg);
--IP; // Insert the next instruction before this one.
TargetReg = Reg; // Codegen the rest of the GEP into this
} else {
unsigned idxReg = getReg(idx, MBB, IP);
unsigned OffsetReg = makeAnotherReg(Type::UIntTy);
// Make sure we can back the iterator up to point to the first
// instruction emitted.
MachineBasicBlock::iterator BeforeIt = IP;
if (IP == MBB->begin())
BeforeIt = MBB->end();
else
--BeforeIt;
doMultiplyConst(MBB, IP, OffsetReg, Type::IntTy, idxReg, elementSize);
// Emit an ADD to add OffsetReg to the basePtr.
unsigned Reg = makeAnotherReg(Type::UIntTy);
BuildMI(*MBB, IP, PPC32::ADD, 2, TargetReg).addReg(Reg).addReg(OffsetReg);
// Step to the first instruction of the multiply.
if (BeforeIt == MBB->end())
IP = MBB->begin();
else
IP = ++BeforeIt;
TargetReg = Reg; // Codegen the rest of the GEP into this
}
}
}
}
@ -2821,7 +2855,7 @@ void ISel::visitMallocInst(MallocInst &I) {
std::vector<ValueRecord> Args;
Args.push_back(ValueRecord(Arg, Type::UIntTy));
MachineInstr *TheCall =
BuildMI(PPC32::CALLpcrel, 1).addExternalSymbol("malloc", true);
BuildMI(PPC32::CALLpcrel, 1).addGlobalAddress(mallocFn, true);
doCall(ValueRecord(getReg(I), I.getType()), TheCall, Args, false);
}
@ -2833,7 +2867,7 @@ void ISel::visitFreeInst(FreeInst &I) {
std::vector<ValueRecord> Args;
Args.push_back(ValueRecord(I.getOperand(0)));
MachineInstr *TheCall =
BuildMI(PPC32::CALLpcrel, 1).addExternalSymbol("free", true);
BuildMI(PPC32::CALLpcrel, 1).addGlobalAddress(freeFn, true);
doCall(ValueRecord(0, Type::VoidTy), TheCall, Args, false);
}