Reapply things reverted back in 97220, with the fixed test case.

llvm-svn: 97228
This commit is contained in:
Sanjiv Gupta 2010-02-26 17:59:28 +00:00
parent 952f6f98bb
commit 2bdbb3c167
5 changed files with 70 additions and 19 deletions

View File

@ -158,6 +158,7 @@ bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
// printOperand - print operand of insn.
void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
const MachineOperand &MO = MI->getOperand(opNum);
const Function *F = MI->getParent()->getParent()->getFunction();
switch (MO.getType()) {
case MachineOperand::MO_Register:
@ -190,19 +191,18 @@ void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
}
case MachineOperand::MO_ExternalSymbol: {
const char *Sname = MO.getSymbolName();
std::string Printname = Sname;
// If its a libcall name, record it to decls section.
if (PAN::getSymbolTag(Sname) == PAN::LIBCALL)
LibcallDecls.push_back(Sname);
// Record a call to intrinsic to print the extern declaration for it.
std::string Sym = Sname;
if (PAN::isMemIntrinsic(Sym)) {
Sym = PAN::addPrefix(Sym);
LibcallDecls.push_back(createESName(Sym));
// Intrinsic stuff needs to be renamed if we are printing IL fn.
if (PAN::isIntrinsicStuff(Printname)) {
if (PAN::isISR(F->getSection())) {
Printname = PAN::Rename(Sname);
}
// Record these decls, we need to print them in asm as extern.
LibcallDecls.push_back(createESName(Printname));
}
O << Sym;
O << Printname;
break;
}
case MachineOperand::MO_MachineBasicBlock:
@ -248,8 +248,6 @@ void PIC16AsmPrinter::printLibcallDecls() {
for (std::list<const char*>::const_iterator I = LibcallDecls.begin();
I != LibcallDecls.end(); I++) {
O << MAI->getExternDirective() << *I << "\n";
O << MAI->getExternDirective() << PAN::getArgsLabel(*I) << "\n";
O << MAI->getExternDirective() << PAN::getRetvalLabel(*I) << "\n";
}
O << MAI->getCommentString() << "External decls for libcalls - END." <<"\n";
}

View File

@ -178,18 +178,21 @@ namespace llvm {
return Func1 + tag;
}
// Get the retval label for the given function.
static std::string getRetvalLabel(const std::string &Func) {
std::string Func1 = addPrefix(Func);
std::string tag = getTagName(RET_LABEL);
return Func1 + tag;
}
// Get the argument label for the given function.
static std::string getArgsLabel(const std::string &Func) {
std::string Func1 = addPrefix(Func);
std::string tag = getTagName(ARGS_LABEL);
return Func1 + tag;
}
// Get the tempdata label for the given function.
static std::string getTempdataLabel(const std::string &Func) {
std::string Func1 = addPrefix(Func);
std::string tag = getTagName(TEMPS_LABEL);
@ -263,6 +266,7 @@ namespace llvm {
return false;
}
inline static bool isMemIntrinsic (const std::string &Name) {
if (Name.compare("@memcpy") == 0 || Name.compare("@memset") == 0 ||
Name.compare("@memmove") == 0) {
@ -272,6 +276,41 @@ namespace llvm {
return false;
}
// Currently names of libcalls are assigned during TargetLowering
// object construction. There is no provision to change the when the
// code for a function IL function being generated.
// So we have to change these names while printing assembly.
// We need to do that mainly for names related to intrinsics. This
// function returns true if a name needs to be cloned.
inline static bool isIntrinsicStuff(const std::string &Name) {
// Return true if the name contains LIBCALL marker, or a MemIntrinisc.
// these are mainly ARGS_LABEL, RET_LABEL, and the LIBCALL name itself.
if ((Name.find(getTagName(LIBCALL)) != std::string::npos)
|| isMemIntrinsic(Name))
return true;
return false;
}
// Rename the name for IL.
inline static std::string Rename(const std::string &Name) {
std::string Newname;
// If its a label (LIBCALL+Func+LABEL), change it to
// (LIBCALL+Func+IL+LABEL).
TAGS id = getSymbolTag(Name);
if (id == ARGS_LABEL || id == RET_LABEL) {
std::size_t pos = Name.find(getTagName(id));
Newname = Name.substr(0, pos) + ".IL" + getTagName(id);
return Newname;
}
// Else, just append IL to name.
return Name + ".IL";
}
inline static bool isLocalToFunc (std::string &Func, std::string &Var) {
if (! isLocalName(Var)) return false;

View File

@ -1527,10 +1527,24 @@ bool PIC16TargetLowering::NeedToConvertToMemOp(SDValue Op, unsigned &MemOp,
return true;
if (isDirectLoad(Op.getOperand(1))) {
if (Op.getOperand(1).hasOneUse())
return false;
else
MemOp = 1;
if (Op.getOperand(1).hasOneUse()) {
// Legal and profitable folding check uses the NodeId of DAG nodes.
// This NodeId is assigned by topological order. Therefore first
// assign topological order then perform legal and profitable check.
// Note:- Though this ordering is done before begining with legalization,
// newly added node during legalization process have NodeId=-1 (NewNode)
// therefore before performing any check proper ordering of the node is
// required.
DAG.AssignTopologicalOrder();
// Direct load operands are folded in binary operations. But before folding
// verify if this folding is legal. Fold only if it is legal otherwise
// convert this direct load to a separate memory operation.
if(ISel->IsLegalToFold(Op.getOperand(1), Op.getNode(), Op.getNode()))
return false;
else
MemOp = 1;
}
}
return true;
}

View File

@ -218,8 +218,8 @@ void PIC16Cloner::cloneSharedFunctions(CallGraphNode *CGN) {
// Such a case may occur when the function has been declarated
// in the C source code but its body exists in assembly file.
if (!CalledF->isDeclaration()) {
cloneFunction(CalledF);
// FIXME: remap all the call sites here.
Function *cf = cloneFunction(CalledF);
remapAllSites(CGN->getFunction(), CalledF, cf);
} else {
// It is called only from ISR. Still mark it as we need this info
// in code gen while calling intrinsics.Function is not marked.

View File

@ -1,4 +1,4 @@
; RUN: llc < %s -march=pic16 | grep "extern @.lib.unordered.f32" | count 3
; RUN: llc < %s -march=pic16 | grep "extern" | grep "@.lib.unordered.f32" | count 3
@pc = global i8* inttoptr (i64 160 to i8*), align 1 ; <i8**> [#uses=2]
@aa = common global i16 0, align 1 ; <i16*> [#uses=0]