[llvm-commits] [llvm] r96175 - /llvm/trunk/lib/Target/PIC16/PIC16MemSelOpt.cpp

Sanjiv Gupta sanjiv.gupta at microchip.com
Sun Feb 14 10:27:42 PST 2010


Author: sgupta
Date: Sun Feb 14 12:27:42 2010
New Revision: 96175

URL: http://llvm.org/viewvc/llvm-project?rev=96175&view=rev
Log:
fixes to pagesel/banksel inserter.
1. restore these across direct/indirect calls.
2. restore pagesel for any macros with gotos.


Modified:
    llvm/trunk/lib/Target/PIC16/PIC16MemSelOpt.cpp

Modified: llvm/trunk/lib/Target/PIC16/PIC16MemSelOpt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16MemSelOpt.cpp?rev=96175&r1=96174&r2=96175&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16MemSelOpt.cpp (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16MemSelOpt.cpp Sun Feb 14 12:27:42 2010
@@ -59,6 +59,7 @@
     const TargetInstrInfo *TII; // Machine instruction info.
     MachineBasicBlock *MBB;     // Current basic block
     std::string CurBank;
+    int PageChanged;
 
   };
   char MemSelOpt::ID = 0;
@@ -93,10 +94,56 @@
   // Let us assume that when entering a basic block now bank is selected.
   // Ideally we should look at the predecessors for this information.
   CurBank=""; 
+  PageChanged=0;
 
-  for (MachineBasicBlock::iterator I = BB.begin(); I != BB.end(); ++I) {
+  MachineBasicBlock::iterator I;
+  for (I = BB.begin(); I != BB.end(); ++I) {
     Changed |= processInstruction(I);
+
+    // if the page has changed insert a page sel before 
+    // any instruction that needs one
+    if (PageChanged == 1)
+    {
+      // Restore the page if it was changed, before leaving the basic block,
+      // because it may be required by the goto terminator or the fall thru
+      // basic blcok.
+      // If the terminator is return, we don't need to restore since there
+      // is no goto or fall thru basic block.
+      if ((I->getOpcode() == PIC16::sublw_3) || //macro has goto
+          (I->getOpcode() == PIC16::sublw_6) || //macro has goto
+          (I->getOpcode() == PIC16::addlwc)  || //macro has goto
+          (TII->get(I->getOpcode()).isBranch()))
+      {
+        DebugLoc dl = I->getDebugLoc();
+        BuildMI(*MBB, I, dl, TII->get(PIC16::pagesel)).addExternalSymbol("$");
+        Changed = true;
+        PageChanged = 0;	    
+      }
+    }
   }
+
+   // The basic block is over, but if we did not find any goto yet,
+   // we haven't restored the page.
+   // Restore the page if it was changed, before leaving the basic block,
+   // because it may be required by fall thru basic blcok.
+   // If the terminator is return, we don't need to restore since there
+   // is fall thru basic block.
+   if (PageChanged == 1) {
+      // save the end pointer before we move back to last insn.
+     MachineBasicBlock::iterator J = I;
+     I--;
+     const TargetInstrDesc &TID = TII->get(I->getOpcode());
+     if (! TID.isReturn())
+     {
+       DebugLoc dl = I->getDebugLoc();
+       BuildMI(*MBB, J, dl, 
+               TII->get(PIC16::pagesel)).addExternalSymbol("$");
+       Changed = true;
+       PageChanged = 0;
+     }
+   }
+
+
   return Changed;
 }
 
@@ -112,42 +159,74 @@
   if (!(TID.isBranch() || TID.isCall() || TID.mayLoad() || TID.mayStore()))
     return false;
 
+  // The first thing we should do is that record if banksel/pagesel are
+  // changed in an unknown way. This can happend via any type of call. 
+  // We do it here first before scanning of MemOp / BBOp as the indirect
+  // call insns do not have any operands, but they still may change bank/page.
+  if (TID.isCall()) {
+    // Record that we have changed the page, so that we can restore it
+    // before basic block ends.
+    // We require to signal that a page anc bank change happened even for
+    // indirect calls. 
+    PageChanged = 1;
+
+    // When a call is made, there may be banksel for variables in callee.
+    // Hence the banksel in caller needs to be reset.
+    CurBank = "";
+  }
+
   // Scan for the memory address operand.
   // FIXME: Should we use standard interfaces like memoperands_iterator,
   // hasMemOperand() etc ?
   int MemOpPos = -1;
+  int BBOpPos = -1;
   for (unsigned i = 0; i < NumOperands; i++) {
     MachineOperand Op = MI->getOperand(i);
     if (Op.getType() ==  MachineOperand::MO_GlobalAddress ||
-        Op.getType() ==  MachineOperand::MO_ExternalSymbol || 
-        Op.getType() ==  MachineOperand::MO_MachineBasicBlock) {
+        Op.getType() ==  MachineOperand::MO_ExternalSymbol) { 
       // We found one mem operand. Next one may be BS.
       MemOpPos = i;
-      break;
+    }
+    if (Op.getType() ==  MachineOperand::MO_MachineBasicBlock) {
+      // We found one BB operand. Next one may be pagesel.
+      BBOpPos = i;
     }
   }
 
   // If we did not find an insn accessing memory. Continue.
-  if (MemOpPos == -1) return Changed;
+  if ((MemOpPos == -1) &&
+      (BBOpPos == -1))
+    return false;
+  assert ((BBOpPos != MemOpPos) && "operand can only be of one type");
  
-  // Get the MemOp.
-  MachineOperand &Op = MI->getOperand(MemOpPos);
 
   // If this is a pagesel material, handle it first.
-  if (MI->getOpcode() == PIC16::CALL ||
-      MI->getOpcode() == PIC16::br_uncond) {
+  // CALL and br_ucond insns use MemOp (GA or ES) and not BBOp.
+  // Pagesel is required only for a direct call.
+  if ((MI->getOpcode() == PIC16::CALL)) {
+    // Get the BBOp.
+    MachineOperand &MemOp = MI->getOperand(MemOpPos);
     DebugLoc dl = MI->getDebugLoc();
-    BuildMI(*MBB, MI, dl, TII->get(PIC16::pagesel)).
-      addOperand(Op);
-    return true;
+    BuildMI(*MBB, MI, dl, TII->get(PIC16::pagesel)).addOperand(MemOp);   
+
+    // CALL and br_ucond needs only pagesel. so we are done.
+    return true; 
   }
 
+  // Pagesel is handled. Now, add a Banksel if needed.
+  if (MemOpPos == -1) return Changed;
+  // Get the MemOp.
+  MachineOperand &Op = MI->getOperand(MemOpPos);
+
   // 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;
+  bool hasExternalLinkage = false;
   if (Op.getType() ==  MachineOperand::MO_GlobalAddress &&
       Op.getGlobal()->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE) {
+    if (Op.getGlobal()->hasExternalLinkage())
+      hasExternalLinkage= true;
     NewBank = Op.getGlobal()->getSection();
   } else if (Op.getType() ==  MachineOperand::MO_ExternalSymbol) {
     // External Symbol is generated for temp data and arguments. They are
@@ -162,7 +241,7 @@
 
   // If the previous and new section names are same, we don't need to
   // emit banksel. 
-  if (NewBank.compare(CurBank) != 0 ) {
+  if (NewBank.compare(CurBank) != 0 || hasExternalLinkage) {
     DebugLoc dl = MI->getDebugLoc();
     BuildMI(*MBB, MI, dl, TII->get(PIC16::banksel)).
       addOperand(Op);





More information about the llvm-commits mailing list