Use StringRef (again) in DebugInfo interface.
[oota-llvm.git] / lib / Target / PIC16 / PIC16MemSelOpt.cpp
index 0458c5a4174f0c73304191359f8860d775ad960b..cc71b04cc2021b0770811098fa07861a4a98bb33 100644 (file)
@@ -21,8 +21,9 @@
 
 #define DEBUG_TYPE "pic16-codegen"
 #include "PIC16.h"
+#include "PIC16ABINames.h"
 #include "PIC16InstrInfo.h"
-#include "PIC16TargetAsmInfo.h"
+#include "PIC16MCAsmInfo.h"
 #include "PIC16TargetMachine.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/GlobalValue.h"
 #include "llvm/DerivedTypes.h"
-#include "llvm/Support/Compiler.h"
 
 using namespace llvm;
 
 namespace {
-  struct VISIBILITY_HIDDEN MemSelOpt : public MachineFunctionPass {
+  struct MemSelOpt : public MachineFunctionPass {
     static char ID;
     MemSelOpt() : MachineFunctionPass(&ID) {}
 
@@ -104,9 +104,13 @@ bool MemSelOpt::processInstruction(MachineInstr *MI) {
   bool Changed = false;
 
   unsigned NumOperands = MI->getNumOperands();
-  // If this insn has only one operand, probably it is not going to
-  // access any data memory.
-  if (PIC16InstrInfo::hasNoMemOperand(*MI)) return Changed;
+  if (NumOperands == 0) return false;
+
+
+  // If this insn is not going to access any memory, return.
+  const TargetInstrDesc &TID = TII->get(MI->getOpcode());
+  if (!(TID.isBranch() || TID.isCall() || TID.mayLoad() || TID.mayStore()))
+    return false;
 
   // Scan for the memory address operand.
   // FIXME: Should we use standard interfaces like memoperands_iterator,
@@ -115,8 +119,9 @@ bool MemSelOpt::processInstruction(MachineInstr *MI) {
   for (unsigned i = 0; i < NumOperands; i++) {
     MachineOperand Op = MI->getOperand(i);
     if (Op.getType() ==  MachineOperand::MO_GlobalAddress ||
-        Op.getType() ==  MachineOperand::MO_ExternalSymbol) {
-      // We found one mem operand. Next one should be BS.
+        Op.getType() ==  MachineOperand::MO_ExternalSymbol || 
+        Op.getType() ==  MachineOperand::MO_MachineBasicBlock) {
+      // We found one mem operand. Next one may be BS.
       MemOpPos = i;
       break;
     }
@@ -129,7 +134,8 @@ bool MemSelOpt::processInstruction(MachineInstr *MI) {
   MachineOperand &Op = MI->getOperand(MemOpPos);
 
   // If this is a pagesel material, handle it first.
-  if (MI->getOpcode() == PIC16::CALL) {
+  if (MI->getOpcode() == PIC16::CALL ||
+      MI->getOpcode() == PIC16::br_uncond) {
     DebugLoc dl = MI->getDebugLoc();
     BuildMI(*MBB, MI, dl, TII->get(PIC16::pagesel)).
       addOperand(Op);
@@ -137,6 +143,8 @@ bool MemSelOpt::processInstruction(MachineInstr *MI) {
   }
 
   // Get the section name(NewBank) for MemOp.
+  // This assumes that the section names for globals are already set by
+  // AsmPrinter->doInitialization.
   std::string NewBank = CurBank;
   if (Op.getType() ==  MachineOperand::MO_GlobalAddress &&
       Op.getGlobal()->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE) {
@@ -145,9 +153,13 @@ bool MemSelOpt::processInstruction(MachineInstr *MI) {
     // External Symbol is generated for temp data and arguments. They are
     // in fpdata.<functionname>.# section.
     std::string Sym = Op.getSymbolName();
-    NewBank = getSectionNameForSym(Sym);
+    NewBank = PAN::getSectionNameForSym(Sym);
   }
+
+  // If the section is shared section, do not emit banksel.
+  if (NewBank == PAN::getSharedUDataSectionName())
+    return Changed;
+
   // If the previous and new section names are same, we don't need to
   // emit banksel. 
   if (NewBank.compare(CurBank) != 0 ) {